Is there any major difference between using
public TValue SomeFunctionA<TValue>(BaseClass<TValue> bc)
over
public TValue SomeFunctionB<TValue, TBaseClass>(TBaseClass bc)
where TBaseClass : BaseClass<TValue>
I've done some testing, and I can't seem to find any difference. All derived classes behave as they should (override something, new something, etc.).
What about if 'TValue' is known, such as (besides now you can use operators):
public int SomeFunctionAInt(BaseClass<int> bc)
and
public int SomeFunctionBInt<TBaseClass>(TBaseClass bc)
where TBaseClass : BaseClass<int>
In this case there is no difference. Generics are used to flow type information. As soon as you want to call other code, or return a value and that value must be statically typed to be the same as the input parameter bc
, you need generics.
For example, the two functions below output the same thing, but the 2nd preserves type information:
object PrintAndReturn1(object obj) { Console.WriteLine(obj); return obj; }
T PrintAndReturn2<T>(T obj) { Console.WriteLine(obj); return obj; }
Generics come into play when you want to preserve type information. If you only ever consume a value and not pass it around, inheritance is enough.
You say you found no difference during testing. This makes sense because the JIT erases the generic type information (mostly). The JITed code will look very similar for both variants. Virtual calls on references of a generic type are implemented the same way as non-generic v-calls. (Note, that this goes for reference types only. All ref types share one JITed code body.)
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