我有一个抽象类Creature,它带有一个通用类型参数,并由其他两个类Human和Spider扩展。每个子类都定义其父级的通用类型。
我对如何将子类作为父类的引用传递给方法感到困惑。
public interface IDamagable
{
void OnSimpleHit();
}
public interface IStabAble : IDamagable
{
void OnKnifeStab();
}
public interface ISlapAble : IDamagable
{
void OnSlap();
}
public abstract class Creature<T> where T : IDamagable
{
public abstract void Init(T damageListener);
}
public abstract class Human : Creature<ISlapAble>
{
}
public abstract class Spider : Creature<IStabAble>
{
}
public class MainClass
{
public void Test()
{
List<Spider> spiderList = new List<Spider>();
List<Human> humanList = new List<Human>();
PrintList<IDamagable>(spiderList); // Argument `#1' cannot convert
//`System.Collections.Generic.List<newAd.B_A_A>' expression
//to type `System.Collections.Generic.List<newAd.A_A<newAd.I_B>>'
}
protected void PrintList<T>(List<Creature<T>> list)
{
}
}
如果PrintList接受2个通用参数,则不会引发错误
protected void PrintList<T,U>(List<T> list) where T : Creature<U> where U : IDamagable
{
}
但是然后我不想再传递U,因为T已经使用U作为类型参数构造了,例如Spider已经定义了Creature以使用IStabAble的类型参数。
因此,基本上,我坚持如何编写该方法,以便它以最少的通用参数同时满足Spider和Human的要求。
谢谢
我假设PrintList
只需要对列表的只读只读访问权限。
解决方案是使该PrintList
方法接受IEnumerable<Creature<T>>
如下所示:
void PrintList<T>(IEnumerable<Creature<T>> list) where T: IDamagable
{
//...
}
并这样称呼它:
PrintList(spiderList);
因为T
in中的泛型类型参数IEnumerable<T>
是covariant,所以这将起作用。
在特殊情况下,因为您使用的是.NET 2.0(不支持协变量类型参数),所以该解决方案将不起作用。这是一种解决方法:
创建一个Cast
可以在具有不同项目类型的枚举数之间进行转换的方法(在.NET 3.5中,我们已经有了诸如扩展方法之类的方法):
public static IEnumerable<U> Cast<T, U>(IEnumerable<T> source) where T : U
{
foreach (var item in source)
{
yield return item;
}
}
并像这样使用它:
PrintList(Cast<Spider, Creature<IStabAble>>(spiderList));
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句