避免传递扩展泛型类的泛型类型参数 [英] Avoid passing generic type parameter of class extending generic class
问题描述
我有一个抽象类Creature,它接受一个泛型类型参数,由另外两个类Human和Spider扩展。每个子类都定义其父类的通用类型。
我坚持如何将子类作为父类的引用传递给方法。
public interface IDamagable
{
void OnSimpleHit();
}
public interface IStabAble:IDamagable
{
void OnKnifeStab();
}
public interface ISlapAble:IDamagable
{
void OnSlap();
}
公共抽象类生物< T>其中T:IDamagable
{
public abstract void Init(T damageListener);
}
公共抽象类人类:生物< ISlapAble>
{
}
公共抽象类Spider:Creature< IStabAble>
{
}
public class MainClass
{
public void Test()
{
List<蜘蛛> spiderList =新列表< Spider>();
列表< Human> humanList = new List< Human>();
PrintList< IDamagable>(spiderList); //参数`#1'不能转换
//`System.Collections.Generic.List<newAd.B_A_A>'表达式
//键入`System.Collections.Generic.List< newAd.A_A< ; newAd.I_B>>'
}
protected void PrintList< T>(List< Creature< T> list)
{
}
}
如果PrintList带2个泛型参数, (T> list>)其中T:生物< U> U:IDamagable
{
}
不想再传递U,因为T已经以U作为类型参数构建,例如Spider已经定义了Creature采用IStabAble的类型参数。
因此基本上,我坚持写如何编写这样的方法,以满足蜘蛛和人类的最少数量的通用参数。
Thanks
我假设 PrintList
只需要只读的只进入列表。
解决方案是让 PrintList
方法接受一个 IEnumerable< Creature< T>>< / code>像这样:
void PrintList< T>(IEnumerable< Creature T> list)其中T:IDamagable
{
// ...
}
并且像这样调用它:
PrintList(spiderList);
因为泛型类型参数 创建一个 并且像这样使用它: I have an abstract class Creature that takes a generic type argument, extended by two other classes Human and Spider. Each subclass defines the generic type of its parent. I am stuck with how to pass a subclass as a reference of parent class to a method. This doesnt throw error if PrintList took 2 generic arguments But then I don't want to pass U again, as T was already constructed with U as type parameter, e.g Spider already defined Creature to take type parameter of IStabAble. So basically, I'm stuck with how to write the method such that it caters both Spider and Human with minimal number of generic parameters. I am assuming that The solution is to make the And call it like this: Because the generic type parameter In your special case, because you are using .NET 2.0 (which does not support covariant type parameters) this solution will not work. Here is a workaround: Create a And use it like this:
这篇关于避免传递扩展泛型类的泛型类型参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! T
in IEnumerable< T>
是
Cast
方法,可以在不同项目类型的枚举类型之间进行转换,如.NET 3.5,我们已经有了扩展方法这样的方法):
public static IEnumerable< U> Cast< T,U>(IEnumerable< T> source)其中T:U
{
foreach(源中的var项)
{
yield return item;
}
}
PrintList(Cast< Spider,Creature< IStabAble>>(spiderList));
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)
{
}
}
protected void PrintList<T,U>(List<T> list) where T : Creature<U> where U : IDamagable
{
}
ThanksPrintList
only requires read-only forward-only access to the list.PrintList
method accept an IEnumerable<Creature<T>>
like this:void PrintList<T>(IEnumerable<Creature<T>> list) where T: IDamagable
{
//...
}
PrintList(spiderList);
T
in IEnumerable<T>
is covariant, this will work.Cast
method that can convert between enumerables with different item types like this (in .NET 3.5, we already have such method as an extension method):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));