c# - 请帮助我理解在 C# 中使用泛型时的多态性

标签 c# asp.net generics asp.net-mvc-2 nested-generics

在使用泛型时,我无法理解多态性的工作原理。例如,我定义了以下程序:

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;

所以,至少我没有完全误解这一点。我不确定我该如何编写一个方法来接受符合相同接口(interface)的类的通用集合。

如果需要的话,我有一个完全解决这个问题的计划,但我真的更愿意正确地做到这一点。

提前谢谢你。

最佳答案

注意:在所有情况下,您都必须初始化 Contents字段到实现 IList<?> 的具体对象

当您保留通用约束时,您可以:

public IList<T> Contents = new List<T>();

当你不这样做时,你可以这样做:

public IList<MyInterface> Contents = new List<MyInterface>();

方法一:

将方法更改为:

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);

方法二:

或者,移动 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();

方法三:

编辑:另一种选择是从 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 list 将接受实现 MyInterface 的对象的任意组合.

关于c# - 请帮助我理解在 C# 中使用泛型时的多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3565582/

相关文章:

c# - 将私钥导出为字节数组的最佳方式

c# - 打开远程计算机上的文件

c# - Dropbox 整合

php - 如果已发送部分响应(分块),如何将浏览器发送到错误页面

c# 泛型约束哪里不是类?

c# - ASP.NET Core 中的 MD5CryptoServiceProvider

c# - 将 rdf 转换为 xml

mysql - Visual Studio 配置数据源 MySQL

c# - 这是将 List<T> 从模型转换为 View 中的 ObservableCollection<T> 的最佳方式吗?

java - 找不到符号/无法使用泛型中的 ArrayList 将对象转换为可比较的对象