让我们想象一个通用方法:
public void DoSomething<T>(ref T value) where T : struct
{
if(value is float)
{
value = (T)0.5f;
}
}
这行不通。搜索互联网,我发现解决方案是:
value = (T)(object) 0.5f;
我只是好奇,既然是装箱和解箱值,是不是分配了额外的内存,需要垃圾回收?没有其他更好的方法将浮点值分配给通用变量吗?
编译器不一定考虑运行时会发生什么。您的if
语句将保证,在运行时,如果if
块内的行未float
T
但编译器不考虑这一点,则永远不会执行该行。当它计算此行时:
value = (T)0.5f;
它所关心的只是该演员表是否适用于所有T
。它不是,所以代码不会编译。在这种情况下:
value = (T)(object) 0.5f;
从float
到object
的强制转换有效,从object
到T
的强制转换对所有T
都有效,因此代码将编译。请注意,由于同样的原因,此代码无法编译:
public void DoSomething<T>(ref T value) where T : struct
{
if (value is float)
{
value = (T)"Hello World";
}
}
虽然此代码出于同样的原因进行编译:
public void DoSomething<T>(ref T value) where T : struct
{
if (value is float)
{
value = (T)(object)"Hello World";
}
}
显然,最后一个代码片段会在运行时引发异常,但正如我所说,编译器不会考虑所有潜在的执行路径,以及哪些路径可以在运行时发生,哪些不能发生。将string
转换为T
无效,而将string
转换为object
,object
转换为T
两者。