C# 泛型和泛型约束

标签 c# inheritance generics generic-constraints generic-function

我正在编写一个带有类型参数 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,或拥有我的任何其他成员。

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

但是我遇到了一个编译时错误:

Type T' does not contain a definition formY' and no extension method mY' of typeT' could be found (are you missing a using directive or an assembly reference?)

我还尝试限制为多个派生类:

public class A<T> where T : E, F

但是我也遇到了如下错误:

The class type constraint 'F' must be listed before any other constraints. Consider moving type constraint to the beginning of the constraint list

我试过切换它们:

public class A<T> where T : F, E

同样,结果是相同的错误,但将 F 切换为 E。

我正在尝试的是可能的吗?我做错了什么?

同样,我无法更改 C、D、E 和 F 类的任何内容。

最佳答案

在A的泛型参数上添加约束时,

public class A<T> where T : D

出现第二个错误的原因是,类型 T' 不包含 mY' 的定义并且找不到类型 T' 的扩展方法 mY'(您是否缺少 using 指令或程序集引用?) 不出所料,因为 D 没有 mY,只有派生类 E 和 F。原因

public class A<T> where T : E, F

不起作用是因为您只能指定一个基类类型约束(C# 没有多重继承)。任何进一步的约束都必须是接口(interface),或者像 classnew()

这样的东西

如果您真的不能改变这些类的任何内容,那么您想要完成的事情可能会异常困难,据我所知。我可以想到一些丑陋的方法(反射或大量转换),但这不是正确的方法。也许我缺少一些聪明的东西。如果您可以引入一个具有 mY 属性的接口(interface)(或中间类),并让 E 和 F 继承自该接口(interface),那就太好了。然后你可以将 T 限制为那个而不是 D 并且一切都将是 honkey dory。否则我看不出有什么方法可以知道你正在处理哪种类型的 D,除非在运行时。

关于C# 泛型和泛型约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11024572/

相关文章:

c# - 从 C# 显示关闭对话框

c# - DateTime 的默认时间精度是多少?

C# : Making an exe to not run directly

python - PySide 浏览器位于单独的进程中

c++ - 创建派生类对象的指针数组。 C++。抽象基类

java - 列表与列表<Object>

c# - 如何按从数据库中检索到的特定顺序显示表单项?

c# - 协方差胜过具体类型?

c# - 使用 Type 参数作为返回类型

scala - 使用内部类作为类型参数