我正在编写一个带有类型参数T的通用抽象类A,我打算用B类派生它。
A有一个数据成员mX,一个C类实例,带有泛型函数。这个泛型函数GetAllOfType()有一个类型参数T.这个类型参数被约束到第三个类,D。GetAllOfType()搜索D的实例容器,其中包括D的派生类的实例,并返回类型为T的子集(因此约束为D)。
D类本身没有特定的数据成员,int mY,但有些D的派生类,例如E和F.
public class D
{
}
public class E : D
{
public int mY;
}
public class F : D
{
public int mY;
}
public class C
{
public T[] GetAllOfType<T>() where T : D
{ ... }
}
public class A<T>
{
private C mX;
...
}
public class B : A<E>
{
...
}
所以我的问题就在这里:
类B用于继承和实现类A的参数类型是D的派生类。我试图在类A中编写一个函数Foo,它通过GetAllOfType()枚举并访问类型为E,F的成员mY,或任何其他有mY的成员。
public class A<T>
{
private C mX;
protected Foo()
{
foreach (var c in mX.GetAllOfType<T>())
{
c.mY = 0;
}
}
}
public class B : A<E>
{
public Bar()
{
Foo();
}
}
问题是,GetAllOfType()是受约束的,我也因为没有约束A类而收到错误。
我已经尝试过限制A:
public class A<T> where T : D
但是我得到的编译时错误如下:
输入
T' does not contain a definition for
mY&#39;没有扩展方法mY' of type
T&#39;可以找到(你错过了使用指令或程序集引用吗?)
我也尝试过限制多个派生类:
public class A<T> where T : E, F
但我也遇到了错误:
班级类型约束&#39; F&#39;必须在任何其他约束之前列出。考虑将类型约束移动到约束列表的开头
我试过切换它们:
public class A<T> where T : F, E
同样,结果是相同的错误,但是为E切换了F。
我尝试的是什么?我做错了什么?
同样,我无法改变C,D,E和F类的任何内容。
答案 0 :(得分:2)
在A的通用参数上添加约束时,
public class A<T> where T : D
你得到第二个错误的原因Type T' does not contain a definition for mY' and no extension method mY' of typeT' could be found (are you missing a using directive or an assembly reference?)
,不出所料,因为D没有mY,只有派生类E和F.原因
public class A<T> where T : E, F
不起作用是因为您只能指定一个基类类型约束(C#没有多重继承)。任何进一步的约束都必须是接口,或class
或new()
如果你真的无法改变关于这些课程的任何内容,那么你想要完成的任务可能是不合理的困难,据我所知。我可以想到一些丑陋的方式(反思,或许多演员),但这不是正确的道路。也许有一些我想念的聪明人。如果你可以引入一个带有mY属性的接口(或一个中间类),并且让E和F继承它,那就太好了。那么你可以将T限制在那而不是D
,而且一切都将是荣誉的。否则,除了在运行时,我看不出任何方式可以知道你正在处理什么类型的D
。