我正在尝试掌握.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可能会.
使用泛型时继承的工作方式不同。正如 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)
我希望这是有帮助的。