我在理解使用泛型时多态如何工作时遇到问题。例如,我定义了以下程序:
public interface IMyInterface
{
void MyMethod();
}
public class MyClass : IMyInterface
{
public void MyMethod()
{
}
}
public class MyContainer<T> where T : IMyInterface
{
public IList<T> Contents;
}
然后,我可以执行此操作,效果很好:
MyContainer<MyClass> container = new MyContainer<MyClass>();
container.Contents.Add(new MyClass());
我有许多实现MyInterface的类。我想编写一个可以接受所有MyContainer对象的方法:
public void CallAllMethodsInContainer(MyContainer<IMyInterface> container)
{
foreach (IMyInterface myClass in container.Contents)
{
myClass.MyMethod();
}
}
现在,我想调用此方法。
MyContainer<MyClass> container = new MyContainer<MyClass>();
container.Contents.Add(new MyClass());
this.CallAllMethodsInContainer(container);
那没用。当然,因为MyClass实现了IMyInterface,所以我应该能够进行转换吗?
MyContainer<IMyInterface> newContainer = (MyContainer<IMyInterface>)container;
那也不起作用。我绝对可以将常规MyClass强制转换为IMyInterface:
MyClass newClass = new MyClass();
IMyInterface myInterface = (IMyInterface)newClass;
因此,至少我还没有完全误解这一点。我不确定我该如何编写一种方法,该方法接受符契约(Contract)一接口(interface)的类的泛型集合。
我有计划在需要时完全解决此问题,但我真的更愿意正确地解决。
先感谢您。
最佳答案
注意:在所有情况下,您都必须将Contents
字段初始化为实现IList<?>
的具体对象
保留通用约束后,您可以执行以下操作:
public IList<T> Contents = new List<T>();
如果不这样做,则可以执行以下操作:
public IList<MyInterface> Contents = new List<MyInterface>();
方法1:
将方法更改为:
public void CallAllMethodsInContainer<T>(MyContainer<T> container) where T : IMyInterface
{
foreach (T myClass in container.Contents)
{
myClass.MyMethod();
}
}
和摘要到:
MyContainer<MyClass> container = new MyContainer<MyClass>();
container.Contents.Add(new MyClass());
this.CallAllMethodsInContainer(container);
方法2:
或者,将
CallAllMethodsInContainer
方法移动到MyContainer<T>
类,如下所示:public void CallAllMyMethodsInContents()
{
foreach (T myClass in Contents)
{
myClass.MyMethod();
}
}
并将代码段更改为:
MyContainer<MyClass> container = new MyContainer<MyClass>();
container.Contents.Add(new MyClass());
container.CallAllMyMethodsInContents();
方法3:
编辑:另一个替代方法是从
MyContainer
类中删除通用约束,如下所示:public class MyContainer
{
public IList<MyInterface> Contents;
}
并将方法签名更改为
public void CallAllMethodsInContainer(MyContainer container)
然后,该代码段应按以下方式工作:
MyContainer container = new MyContainer();
container.Contents.Add(new MyClass());
this.CallAllMethodsInContainer(container);
请注意,使用此替代方法,容器的
Contents
列表将接受实现MyInterface
的对象的任何组合。