这种比较是否会在泛型类中编译为常量布尔值?

时间:2015-12-16 07:18:18

标签: c# compiler-optimization compile-time-constant generic-type-argument

typeof(T) == typeof(string)中的T作为泛型类型参数,将被编译为常量布尔值,因为条件在编译时是可知的吗?

2 个答案:

答案 0 :(得分:4)

IL中存在通用类型数据 - 它不像Java那样被删除。所以:不, C#编译器不会将其编译为常量;它编译了IL,它讨论了泛型类型参数。

JIT 然后重用用于所有引用类型排列(只有每个值类型排列需要单独的JIT,因为大小/装箱/等原因)。由于string是引用类型,这意味着Foo<string>(其中typeof(T)==typeof(string)true)使用与Foo<SomeClass>相同的JIT输出(其中{{1}是typeof(T)==typeof(string))。所以不是:即使在JIT时间,这也是明确的常量。

答案 1 :(得分:0)

我对此进行了一些性能测试,结果如下:

  1. 如果泛型Type是一个类(不是结构),则在以下语句上没有编译器或运行时优化:if(typeof(T)== typeof(someClass))。
  2. 如果泛型类型是结构,则对以下格式的if语句进行编译器或运行时优化:if(typeof(T)== typeof(someStruct)),直至特定点(方法似乎很重要:在998个if语句后的测试装置中)。此后,性能将急剧下降:尽管在此点之前添加此类额外的if语句不会对性能造成任何影响,但在此点之后添加额外的if语句不会导致10000%以上的性能下降。
  3. 将泛型类型限制为某个类或将其限制为结构不会改变性能。
  4. 重要的是方法的大小,而不是类的大小。因此,执行相同操作的10种方法可能比1种大型方法的效果更好。

在VS2017和.net 4.6.2上使用C#测试,并启用了优化功能。