C#中的泛型继承?

11 c# generics inheritance

可能重复:
为什么C#泛型不能像C++模板中那样从泛型类型参数中派生出来?

我可以

public class MyGenericClass : DL
//but i cannot do
public class MyGenericClass <T> : T
Run Code Online (Sandbox Code Playgroud)

我怎么做第二个?如果我不能那样做,我该怎么办呢

public class MyGenericClass <T> 
{
    T obj;
    //have all MyGenericClass.XYZ call obj.XYZ
}
Run Code Online (Sandbox Code Playgroud)

Jas*_*yne 9

这是不可能的,因为根据T的类型,MyGenericClass的公共接口会发生变化.

如果你有很多不同的类都暴露了相同的接口,你可以声明MyGenericClass来公开那个接口,并在所有函数的实现中委托调用obj


eri*_*len 5

你可以做类似的事情

public interface IXyzable { void xyz(); }

public class MyGenericClass<T> : IXyzable where T : IXyzable {
    T obj;
    public void xyz() {
        obj.xyz();
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:现在我明白了这个问题


Dan*_*ker 5

具体问题,为什么你不能这样做:

public class MyGenericClass<T> : T
Run Code Online (Sandbox Code Playgroud)

你可以这样做:

public class MyGenericClass<T> 
{
   T obj;
}
Run Code Online (Sandbox Code Playgroud)

原因是CLR喜欢能够为MyGenericClass编译单个版本的代码,该代码适用于为T指定的任何引用类型.

它可以为第二种情况下做到这一点,因为它可以悄悄地代替Tobject,并插入相应的强制类型转换,大致相当于:

public class MyGenericClass 
{
   object obj;
}
Run Code Online (Sandbox Code Playgroud)

但对于继承版本,该技巧不起作用.

此外,通过界面约束无法描述许多有用的设施.从类型继承时,除了调用方法之外,您还可以做很多事情 - 您也可以覆盖它们.考虑这个假设的例子:

class MyBase 
{
    public virtual void MyVirtual() { }
}

class MyGenericDerived<T> : T
{
    public override void MyVirtual() 
    {
        Console.WriteLine("Overridden!"); 
    }
} 

MyBase obj = new MyGenericDerived<MyBase>();
obj.MyVirtual();
Run Code Online (Sandbox Code Playgroud)

我想要做的就是"混合",其中MyGenericDerived提供虚拟函数的定义,无论它应用于何种基础.但编译器如何知道T将有一个可以覆盖的名为MyVirtual的方法?我需要对T进行约束.如何通过接口表达?不可能.一旦允许从类型参数继承,使用接口来描述约束就不是一个合适的解决方案.这就是今天语言中不存在的另一个原因.