通过泛型接口进行封装的正确方法

本文关键字:方法 封装 泛型接口 | 更新日期: 2023-09-27 18:12:12

我的应用程序由服务器和客户端组成,它们是独立的。它们通过服务器创建和修改的对象进行通信。客户端提供该对象的只读接口。据我所知,这是在OOP中保持封装的正确方法。看到的例子:

// Client-side
interface IBox<T> where T : ITool
{
    IEnumerable<T> Tools { get; }
}
interface ITool
{
    void Use();
}
// Server-side
class Box : IBox<Tool>
{
    public List<Tool> ToolList = new List<Tool>();
    public IEnumerable<ITool> Tools
    {
        get { return ToolList; }
    }
}
class Tool : ITool
{
    string _msg = "default msg";
    public string Msg
    {
        get { return _msg; }
        set { _msg = value; }
    }
    public void Use()
    {
        Console.WriteLine("Tool used! Msg: {0}", _msg);
    }
}

如你所见,我必须使用泛型,因为我的对象形成了一个层次结构。

这看起来不错,直到我决定添加一个Room类与接口IRoom,它不仅必须泛化IBox,但ITool太:

interface IRoom<B, T>
    where B : IBox<T>
    where T : ITool
{
    IEnumerable<B> Boxes { get; }
}
class Room : IRoom<Box, Tool>
{
    public List<Box> BoxList = new List<Box>();
    public IEnumerable<Box> Boxes
    {
        get { return BoxList; }
    }
}

现在,想象我们有一个Room,它不仅由盒子组成。我需要至少3个完全不同的集合,这也是几种类型的集合。所以,肯定有一个巨大的树,我的根类变成了这样的:Room : IRoom<Box, Tool1, Tool2, Tool3, Wardrobe, Coat, Jeans, Hat, Table, Computer, Book, Pen>

我不确定,那是对的。我的问题是,实现任务的真正oop方式是什么?(没有反射,破坏封装,类型转换或其他不良技巧)

通过泛型接口进行封装的正确方法

从。net Framework 4和c# 4开始,你可以使用IEnumerable的协方差,只是避免使用泛型。

// Client-side
interface IBox
{
    IEnumerable<ITool> Tools { get; }
}
interface ITool
{
    void Use();
}
// Server-side
class Box : IBox
{
    public List<Tool> ToolList = new List<Tool>();
    public IEnumerable<ITool> Tools
    {
        get { return ToolList; } // With .NET 3.5 and earlier cast here is neccessary to compile
        // Cast to interfaces shouldn't be so much of a performance penalty, I believe.
    }
}
class Tool : ITool
{
    string _msg = "default msg";
    public string Msg
    {
        get { return _msg; }
        set { _msg = value; }
    }
    public void Use()
    {
        Console.WriteLine("Tool used! Msg: {0}", _msg);
    }
}

interface IRoom
{
    IEnumerable<IBox> Boxes { get; }
}
class Room : IRoom
{
    public List<Box> BoxList = new List<Box>();
    public IEnumerable<IBox> Boxes
    {
        get { return BoxList; } // and here...
    }
}

这里描述的泛型中的协方差和逆变性:http://msdn.microsoft.com/en-us/library/dd799517.aspx