C#?和??运算符以及合并条件表达式

     最近项目中,常常碰到这个?和??这两个操作符,之前说得不够详细,趁着周末补全来,希望能够给大家带来帮助。

  (一)?操作符

     我们知道值类型是不肯能为空的,它总是包含值的本身,不会为NULL,这估计也是值类型的由来。 ?应该是为了解决把值类型设置为可空类型而出现的,比如int? y=null这种情况,当数据库设置某个int类型,datetime类型等等,可以为空的时候,?运算符在我们编程中就会非常有用。其实?这个操作符等价于Nullable<T>。看Nullable<T>的源码可以了解到如下信息: 

namespace System {
    using System.Runtime.InteropServices;
    using System.Runtime.Versioning;

    [Serializable, StructLayout(LayoutKind.Sequential), NonVersionable, __DynamicallyInvokable]
    public struct Nullable<T> where T : struct {
        private bool hasValue;   //这个类似于一个标注位的作用
        internal T value;  
        [NonVersionable, __DynamicallyInvokable]
        public Nullable(T value) {
            this.value = value;
            this.hasValue = true;
        }

        [__DynamicallyInvokable]
        public bool HasValue {
            [NonVersionable, __DynamicallyInvokable]
            get {
                return this.hasValue;
            }
        }
        [__DynamicallyInvokable]
        public T Value {
            [__DynamicallyInvokable]
            get {
                if (!this.hasValue) {
                    ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NoValue);
                }
                return this.value;
            }
        }
        [NonVersionable, __DynamicallyInvokable]
        public T GetValueOrDefault() {
            return this.value;
        }

        [NonVersionable, __DynamicallyInvokable]
        public T GetValueOrDefault(T defaultValue) {
            if (!this.hasValue) {
                return defaultValue; //返回默认值。
            }
            return this.value;
        }

        [__DynamicallyInvokable]
        public override bool Equals(object other) {
            if (!this.hasValue) {
                return (other == null);
            }
            if (other == null) {
                return false;
            }
            return this.value.Equals(other);
        }

        [__DynamicallyInvokable]
        public override int GetHashCode() {
            if (!this.hasValue) {
                return 0;
            }
            return this.value.GetHashCode();
        }

        [__DynamicallyInvokable]
        public override string ToString() {
            if (!this.hasValue) {
                return "";
            }
            return this.value.ToString();
        }

        [NonVersionable, __DynamicallyInvokable]
        public static implicit operator T? (T value) {
            return new T?(value);
        }

        [NonVersionable, __DynamicallyInvokable]
        public static explicit operator T(T? value) {
            return value.Value;
        }
    }
}

     可以看出该结构表示可以为null的值类型,它本身也是轻量级的,实例是存在栈上的,而且实例大小和原始值类型基本一样的,只是多了一个Boolean字段。仔细阅读上面的源码也可以分析出相关的东西。

     (二)?? 空接合操作符

      ??叫做  null 合并运算符。如果此运算符的左操作数不为 null,则此运算符将返回左操作数;否则返回右操作数。可以用来给变量设置默认值。特别提醒: 记住和空有关的时候,才要去用?? 。如果不会有空的判断,就别用了。因为这个是空的合并运算符。也有人说??是?:的语法糖而已,但是实际上??进行了很大改进,能够更好的支持表达式。

   

   (第二种)??在复合情形中,更好用,和上面类似。

   还有就是如何把一个条件表达式,用?和??进行合并。

   var flag = tt == null ? 1 : tt.Name;    因为这里进行了为Null的判断,所以可以用??。先写??。然后再来确定左右两边应该写什么。    var flag= tt?.Name??1 ;这个就是合并后的条件表达式

    (三)CLR对可空类型支持

     C#设计人员想尽一切方法,让可空类型,看起来不要那么另类,看起来像一个一等公民。

     看了它的Nullable<T>的代码就知道了,它其实是一个bool类型字段+值类型。其实它很多操作都可以从这里来解释,装箱,拆箱。

     CLR会说谎----看下图

    

  

posted @ 2017-03-24 13:15  GDOUJKZZ  阅读(1885)  评论(2编辑  收藏  举报