WEB开发网
开发学院软件开发C语言 再谈值类型和null的比较 阅读

再谈值类型和null的比较

 2010-09-30 21:07:04 来源:WEB开发网   
核心提示:原来的随笔回复很多,不方便大家讨论这个诡异的问题了,再谈值类型和null的比较,原文章可以参考这里,里面有详细的说明:谈谈值类型与null的判等比较!通过几天的研究,但是结果始终是确定的,所以这个比较意义不是很大,问题终于有了结果了,分享给大家!我也是请教了一个朋友才了解到这些的

原来的随笔回复很多,不方便大家讨论这个诡异的问题了,原文章可以参考这里,里面有详细的说明:

谈谈值类型与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#编译器的确是允许类似的比较的,他认为这个行为是合法的!这样设计的原因很可能是为了和可空类型在语义上保持一致!

请大家多多指教啊!

Tags:谈值 类型 null

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接