受约束的泛型类型参数的继承 [英] Inheritance on a constrained generic type parameter

查看:20
本文介绍了受约束的泛型类型参数的继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆