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.
You cannot inherit a generic type. // class Derived20 : T {}// NO!
You can constrain the generic type by interface, thereby allowing only classes that implement that interface or classes that inherit from classes that implement the interface as the type parameter. The code below constrains a class to an interface.
The where clause in a generic definition specifies constraints on the types that are used as arguments for type parameters in a generic type, method, delegate, or local function. Constraints can specify interfaces, base classes, or require a generic type to be a reference, value, or unmanaged type.
Value type constraint If we declare the generic class using the following code then we will get a compile-time error if we try to substitute a reference type for the type parameter.
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).
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With