c# – 在受限通用类型参数上的继承

我知道这是不可能继承一个泛型类型的参数,但实现一个抽象类型的派生的共同代理将是方便的:-)

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

实施例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的导数:

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时,FooProxy覆盖Bar()方法的代码将被重用。

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

最佳答案
因为你不能。泛型不是模板。你不应该像C模板那样考虑它们,并期望相同的行为。他们是根本不同的概念。

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

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 library这样的东西可以从中受益。问题是,C模板是编译时“查找和替换”构造,而C#泛型是一个运行时事。

为了演示这个事实,对于这个类:

class Test<T> where T : class {
    // whatever contents it might have...
} 

在编译时和运行时只会发出一个IL,JIT编译器将为所有引用类型类型参数生成一个本地代码。这不像C模板,其中本地代码将为每个T单独发出(它受到优化,但概念上,它们是完全独立的代码段)。

转载注明原文:c# – 在受限通用类型参数上的继承 - 代码日志