再谈值类型和null的比较
2010-09-30 21:07:04 来源:WEB开发网原来的随笔回复很多,不方便大家讨论这个诡异的问题了,原文章可以参考这里,里面有详细的说明:
谈谈值类型与null的判等比较!
通过几天的研究,问题终于有了结果了,分享给大家!
我也是请教了一个朋友才了解到这些的,十分感谢懿民帮助 !
通过查看C#编译器的源代码,我们会发现他在编译以下代码的时候:
public static bool operator ==(MyStruct2 s1, MyStruct2 s2)
{
return s1.Value == s2.Value;
}
需要执行如下代码:
// Equality operators are special. If the return type is bool and the parameter types
// are the same then they treat null as a value and return bool.
if (fEqOp && nin.FAlwaysNull()) {
ASSERT((ek == EK_EQ || ek == EK_NE) && typeRetRaw->isPredefType(PT_BOOL) && paramsRaw->Item(0) == paramsRaw->Item(1));
// At least one of them is a constant null.
EXPR * exprRes;
if (nin.rgfNull[0] && nin.rgfNull[1]) {
// Both are constant nulls.
exprRes = newExprConstant(tree, typeRetRaw, ConstValInit(ek == EK_EQ));
exprRes = AddSideEffects(tree, exprRes, exprVal2, true, true);
return AddSideEffects(tree, exprRes, exprVal1, true, true);
}
if (nin.rgfNull[0] ? !exprVal2->type->isNUBSYM() : !exprVal1->type->isNUBSYM()) {
// One is null and the other is not nullable.
exprRes = newExprConstant(tree, typeRetRaw, ConstValInit(ek == EK_NE));
exprRes = AddSideEffects(tree, exprRes, exprVal2, true, true);
return AddSideEffects(tree, exprRes, exprVal1, true, true);
}
// Generate seq(a, !b.HasValue) or rev(!a.HasValue, b).
exprRes = BindNubHasValue(tree, nin.rgfNull[0] ? exprVal2 : exprVal1, ek == EK_NE);
return AddSideEffects(tree, exprRes, nin.rgfNull[0] ? exprVal1 : exprVal2, nin.rgfNull[0], true);
}
大家注意最上面那行注释:那么判等操作符是特殊的,如果返回值是bool并且参数类型是一样的,那么就把null作为值类型来看待,返回一个bool.
可见,C#编译器是有意这样来设计的,这不是一个bug,值类型只要提供了==运算符重载,并且参数类型是一样的,值类型就可以和null 比较(==,!=,<,>,<=,>=都有类似的特殊性),但是结果始终是确定的,所以这个比较意义不是很大,但是C#编译器的确是允许类似的比较的,他认为这个行为是合法的!这样设计的原因很可能是为了和可空类型在语义上保持一致!
请大家多多指教啊!
赞助商链接