简体   繁体   中英

Is there any appreciable difference between using an abstract class as a method parameter and generic parameter constrained to said abstract class?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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