繁体   English   中英

约束通用类型参数的继承

[英]Inheritance on a constrained generic type parameter

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

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

示例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时,将重用Bar()方法的FooProxy重写中的代码。

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

因为你不能。 泛型不是模板。 您不应该像C ++模板那样考虑它们,并且期望它们具有相同的行为。 它们是根本不同的概念。

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

C#3.0语言规范:类型参数(第4.5节)

类型参数不能直接用于声明基类(第10.2.4节)或接口(第13.1.3节)。

更新:

我了解您想要做什么及其用途。 这是C ++模板的传统用例。 具体来说,如果可以使用C#泛型来实现,那么Moq库之类的东西就可以从中受益。 问题是,C ++模板是编译时的“查找和替换”结构,而C#泛型是运行时的东西。

为了证明这一事实,对于本课程:

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

仅单个IL将在编译时被发射,并在运行时间,JIT编译器将生成所有引用类型的类型参数的单个本地代码。 这根本不像C ++模板,后者将为每个T分别发出本机代码(这是经过优化的,但从概念上讲,它们是完全独立的代码段)。

您不能从泛型类型参数继承,因为类型在编译时是未知的,因此编译器无法弄清楚超类是什么。 我意识到,乍一看,编译器可以弄清楚<T>是什么,这似乎表明它应该能够弄清楚T是什么,但是两者是不同的。

另外,您在Bar中遇到逻辑问题。 您不能调用base.Bar,因为这是抽象类型。 为了纠正此问题,您必须将Foo中的实现更改为

public virtual void Bar() {}

因为Foo是抽象类型。

如果您在类中实现了Foo,然后在模板中使用了Foo,则可以这样做。

您也可以使用界面来执行您认为要执行的操作。

编辑:

仔细考虑一下您的代码,这没有任何意义。 您将需要创建GENERIC类型的基类,然后从该基类派生出来以实现您想要的工作。 这也将使地狱更加有意义...

abstract class Foo<T>  
{  
    public virtual void Bar();  
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM