.NET通用方法问题

Gar*_*ton 5 .net c# generics

我正在尝试掌握.NET Generics的概念,并在我自己的代码中实际使用它们,但我一直遇到问题.

有人可以尝试向我解释为什么以下设置无法编译?

public class ClassA
{
    ClassB b = new ClassB();

    public void MethodA<T>(IRepo<T> repo) where T : ITypeEntity
    {
        b.MethodB(repo);
    }
}

public class ClassB
{
    IRepo<ITypeEntity> repo;

    public void MethodB(IRepo<ITypeEntity> repo)
    {
        this.repo = repo;
    }
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:
无法从IRepo <'T>转换为IRepo <'ITypeEntity>

使用IRepo <'DetailType>对象参数调用MethodA,其中DetailType继承自ITypeEntity.

我一直认为这应该编译,因为我将MethodA中的T限制为ITypeEntity类型.

任何想法或反馈都会非常有帮助.

谢谢.

编辑:尼克R有一个很好的建议,但不幸的是在我的背景下,我没有选择制作ClassA Generic.但是ClassB可能会.

Luc*_*ter 3

使用泛型时继承的工作方式不同。正如 Smashery 指出的,即使 TypeA 继承自 TypeB,myType<TypeA> 也不会继承自 myType<TypeB>。

因此,您无法调用定义为 MethodA(myType<TypeB> b) 的方法,期望得到 myType<TypeB> 并为其提供 myType<TypeA>。相关类型必须完全匹配。因此,以下内容将无法编译:

myType<TypeA> a; // This should be a myType<TypeB>, even if it contains only TypeA's

public void MethodB(myType<TypeB> b){ /* do stuff */ }

public void Main()
{
  MethodB(a);
}
Run Code Online (Sandbox Code Playgroud)

因此,在您的情况下,您需要将 IRepo<ITypeEntity> 传递给 MethodB,即使它只包含 DetailTypes。您需要在两者之间进行一些转换。如果您使用的是通用 IList,您可以执行以下操作:

public void MethodA<T>(IList<T> list) where T : ITypeEntity
{
  IList<T> myIList = new List<T>();

  foreach(T item in list)
  {
    myIList.Add(item);
  }

  b.MethodB(myIList);
}
Run Code Online (Sandbox Code Playgroud)

我希望这是有帮助的。