受约束的泛型类型参数的继承 [英] Inheritance on a constrained generic type parameter
问题描述
我知道不可能从泛型类型参数继承,但是在为抽象类型的派生实现通用代理时会很方便:-)
I know it isn't possible to inherit from a generic type parameter, but it would be handy when implementing a common proxy for derivatives of an abstract type :-)
有人知道为什么这是不可能的吗?
Does anyone know why this isn't possible?
示例 C#:
abstract class Foo
{
public virtual void Bar()
{
// nop
}
}
class FooProxy<TFoo> : TFoo
where TFoo : Foo
{
public override void Bar()
{
// do some stuff before
base.Bar();
// do some stuff after
}
}
一些更多的代码来说明如何使用它的示例.考虑以下 Foo 的导数:
Some more code to illustrate an example of how this could be used. Consider the following derivatives of Foo:
class FooX : Foo
{
public string X { get; set; }
public override void Bar()
{
Console.WriteLine("Doing Bar X");
}
}
class FooY : Foo
{
public string Y { get; set; }
public override void Bar()
{
Console.WriteLine("Doing Bar Y");
}
}
和调用代码:
FooProxy<FooX> fooXProxy = new FooProxy<FooX>();
fooXProxy.X = "test X";
fooXProxy.Bar();
FooProxy<FooY> fooYProxy = new FooProxy<FooY>();
fooYProxy.Y = "test Y";
fooYProxy.Bar();
在使用 FooX 和 FooY 时,Bar() 方法的 FooProxy 覆盖中的代码将被重用.
The code in the FooProxy override of Bar() method will be reused when using FooX and FooY.
根据 Pete OHanlon 的回答修改:使 Bar() 方法成为虚拟的.
Revised as per Pete OHanlon's answer: made Bar() method virtual.
推荐答案
因为你不能.泛型不是模板.您不应该像 C++ 模板一样考虑它们并期望具有相同的行为.它们是根本不同的概念.
Because you can't. Generics are not templates. You shouldn't think about them like C++ templates and expect the same behavior. They are fundamentally different concepts.
C# 规范明确禁止使用类型参数作为基类:
The C# specification explicitly prohibits usage of type parameters as base class:
类型参数不能直接用于声明基类(第 10.2.4 节)或接口(第 13.1.3 节).
C# 3.0 Language Specification: Type Parameters (§4.5)
A type parameter cannot be used directly to declare a base class (§10.2.4) or interface (§13.1.3).
更新:
我了解您想做什么及其用途.这是 C++ 模板的传统用例.具体来说,如果这可以使用 C# 泛型来实现,例如 Moq
库 可以从中受益.问题是,C++ 模板是编译时的查找和替换"构造,而 C# 泛型是运行时的.
Update:
I understand what you want to do and its use. This is a traditional use case of C++ templates. Specifically, if this was possible to do using C# generics, things like Moq
library could benefit from it. The problem is, C++ templates are compile time "find and replace" constructs while C# generics are a run time thing.
为了证明这个事实,对于这个类:
To demonstrate this fact, for this class:
class Test<T> where T : class {
// whatever contents it might have...
}
在编译时和运行时只会发出一个 IL,JIT 编译器将为所有引用类型类型参数生成一个单一本机代码.这与 C++ 模板完全不同,其中将为每个 T
单独发出本机代码(它需要优化,但从概念上讲,它们是完全独立的代码段).
only a single IL will be emitted at compile time and at run time, the JIT compiler would generate a single native code for all reference-type type parameters. This is not like C++ templates at all, where native code would be emitted for every T
separately (it's subject to optimization but conceptually, they are completely separate pieces of code).
这篇关于受约束的泛型类型参数的继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!