使用抽象类作为方法参数和约束到所述抽象类的泛型参数之间是否有任何明显的区别?

Tor*_*ory 7 .net c# vb.net generics abstract-class

使用之间有什么重大区别吗?

 public TValue SomeFunctionA<TValue>(BaseClass<TValue> bc)
Run Code Online (Sandbox Code Playgroud)

过度

 public TValue SomeFunctionB<TValue, TBaseClass>(TBaseClass bc)
      where TBaseClass : BaseClass<TValue>
Run Code Online (Sandbox Code Playgroud)

我做了一些测试,我似乎找不到任何区别.所有派生类的行为都应该如此(覆盖某些东西,新东西等).

如果'TValue'是已知的,例如(除了现在你可以使用运算符):

 public int SomeFunctionAInt(BaseClass<int> bc)
Run Code Online (Sandbox Code Playgroud)

 public int SomeFunctionBInt<TBaseClass>(TBaseClass bc)
      where TBaseClass : BaseClass<int>
Run Code Online (Sandbox Code Playgroud)

usr*_*usr 3

在这种情况下没有区别。泛型用于传递类型信息。一旦您想要调用其他代码,或者返回一个值,并且该值必须静态类型化以与输入参数相同bc,您就需要泛型。

例如,下面的两个函数输出相同的内容,但第二个函数保留类型信息:

object PrintAndReturn1(object obj) { Console.WriteLine(obj); return obj; }
T PrintAndReturn2<T>(T obj) { Console.WriteLine(obj); return obj; }
Run Code Online (Sandbox Code Playgroud)

当您想要保留类型信息时,泛型就会发挥作用。如果您只使用一个值而不传递它,那么继承就足够了。

你说你在测试过程中没有发现任何差异。这是有道理的,因为 JIT 删除了通用类型信息(大部分)。这两种变体的 JIT 代码看起来非常相似。对泛型类型引用的虚拟调用的实现方式与非泛型 v 调用相同。(请注意,这仅适用于引用类型。所有引用类型共享一个 JIT 代码体。)