Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
564 views
in Technique[技术] by (71.8m points)

c# - 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?

Example 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
  }

}

EDIT: 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");
  }
}

And the calling code:

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

FooProxy<FooY> fooYProxy = new FooProxy<FooY>();
fooYProxy.Y = "test Y";
fooYProxy.Bar();

The code in the FooProxy override of Bar() method will be reused when using FooX and FooY.

EDIT: Revised as per Pete OHanlon's answer: made Bar() method virtual.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

The C# specification explicitly prohibits usage of type parameters as base class:

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).

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...
} 

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).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...