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

    请大家多多指教啊!
  • 相关阅读:
    Java调用getResource方法获取文件路径乱码
    Java时间格式转换
    java——枚举类型通过反射获取属性值并合成Map进行对比取值
    JXLS问题
    elementUI——select 根据传入的ID值选中选项
    强、软、弱、虚四种引用的区别
    frp + ssl证书 + 宝塔面板 实现 https 访问内网可道云
    ReentrantLock 公平锁和非公平锁的区别
    Stream流式计算
    四大函数式接口
  • 原文地址:https://www.cnblogs.com/xuefeng1982/p/1604377.html
Copyright © 2011-2022 走看看