我的应用程序由服务器和客户端组成,它们是独立的。它们通过服务器创建和修改的对象进行通信。客户端具有此对象的只读接口。据我所知,这是保持封装在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
:< / p>
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方式是什么? (没有反射,打破封装,打字或其他不良技巧)
答案 0 :(得分:2)
从.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