gpt4 book ai didi

c# - 避免传递扩展泛型类的类的泛型类型参数

转载 作者:行者123 更新时间:2023-11-30 23:25:24 27 4
gpt4 key购买 nike

我有一个抽象类 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);

因为泛型类型参数TIEnumerable<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));

关于c# - 避免传递扩展泛型类的类的泛型类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37296664/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com