zoukankan      html  css  js  c++  java
  • 再谈值类型和null的比较

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

     http://www.cnblogs.com/xuefeng1982/archive/2009/11/13/1602358.html

    通过几天的研究,问题终于有了结果了,分享给大家!


    我也是请教了一个朋友才了解到这些的,十分感谢懿民帮助 !

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

    请大家多多指教啊!
  • 相关阅读:
    [考试反思]0511省选模拟93:平衡
    [考试反思]0509省选模拟92:警示
    [考试反思]0508省选模拟91:小雨
    [考试反思]0507省选模拟90:信任
    [考试反思]0506省选模拟89:无事
    [专题总结]2-sat及题目&题解(3/5 complete)
    [考试反思]0505省选模拟88:滑稽
    [考试反思]0504省选模拟87:开花
    [考试反思]0502省选模拟86:恐惧
    [考试反思]0501省选模拟85:低落
  • 原文地址:https://www.cnblogs.com/xuefeng1982/p/1604377.html
Copyright © 2011-2022 走看看