C# 受约束泛型类型参数上的继承

C# 受约束泛型类型参数上的继承,c#,generics,C#,Generics,我知道不可能从泛型类型参数继承,但在为抽象类型的派生实现公共代理时,它会很方便:-) 有人知道为什么这不可能吗 示例C#: 以及呼叫代码: FooProxy<FooX> fooXProxy = new FooProxy<FooX>(); fooXProxy.X = "test X"; fooXProxy.Bar(); FooProxy<FooY> fooYProxy = new FooProxy<FooY>(); fooYProxy.Y = "t

我知道不可能从泛型类型参数继承,但在为抽象类型的派生实现公共代理时,它会很方便:-)

有人知道为什么这不可能吗

示例C#:

以及呼叫代码:

FooProxy<FooX> fooXProxy = new FooProxy<FooX>();
fooXProxy.X = "test X";
fooXProxy.Bar();

FooProxy<FooY> fooYProxy = new FooProxy<FooY>();
fooYProxy.Y = "test Y";
fooYProxy.Bar();
FooProxy fooXProxy=newfooproxy();
fooXProxy.X=“测试X”;
fooXProxy.Bar();
FooProxy fooYProxy=新的FooProxy();
fooYProxy.Y=“测试Y”;
fooYProxy.Bar();
使用FooX和FooY时,将重用Bar()方法的FooProxy重写中的代码


编辑:根据Pete OHanlon的答案进行修订:使Bar()方法虚拟。

,因为您不能。泛型不是模板。你不应该把它们想象成C++模板,并期待同样的行为。它们是根本不同的概念

C#规范明确禁止将类型参数用作基类:

C#3.0语言规范:类型参数(§4.5) 类型参数不能直接用于声明基类(§10.2.4)或接口(§13.1.3)

更新: 我理解你想做什么,以及它的用途。这是C++模板的一个传统用例。具体来说,如果使用C#泛型可以做到这一点,那么像这样的事情可能会从中受益。问题是,C++模板是编译时“查找和替换”的结构,而C泛型是运行时的事情。p> 为了证明这一事实,对于本课程:

class Test<T> where T : class {
    // whatever contents it might have...
} 
类测试,其中T:class{
//不管它可能有什么内容。。。
} 

编译时只会发出一个IL,在运行时,JIT编译器会为所有引用类型参数生成一个本地代码。这根本不像C++模板,在这里,每个代码分别会被发布给每个代码< t/code >(它是优化的,但在概念上,它们是完全分开的代码块)。

,因为FoO是一个抽象类型。 如果您在类中实现了Foo,然后在模板中使用它,那么您就可以这样做

我相信,你也可以使用一个界面来做你想做的事情

编辑:

仔细想想你的代码,它毫无意义。您需要创建一个GENERIC类型的基类,然后从该基类派生出您想要做的事情。这也会让你觉得更有意义

abstract class Foo<T>  
{  
    public virtual void Bar();  
}
抽象类Foo
{  
公共虚拟空栏();
}

不能从泛型类型参数继承,因为在编译时类型未知,因此编译器无法确定超类是什么。我意识到,乍一看,编译器能够理解什么是,这似乎表明它应该能够理解什么是T,但这两件事是不同的

另外,你在酒吧里有一个逻辑问题。不能调用base.Bar,因为这是一个抽象类型。为了纠正这个问题,您必须将Foo中的实现更改为

public virtual void Bar() {}

我想要投票,但是我认为你的钱,C++模板不是C泛型的……换句话说,一个对象不可能符合派生类的二元布局(它要求基本子对象是固定的、一致的大小)和基类二进制布局。“固定大小的基”要求是由CLR强加的,并不是基本要求——可以存储到每个子对象的偏移量,这也是支持多虚拟继承的语言所需要的——但是.NET选择避免这种额外的复杂性。
abstract class Foo<T>  
{  
    public virtual void Bar();  
}
public virtual void Bar() {}