通常一个值类型变量永远不可能为null,它总是包含值类型的值本身。但是在某些情况下会遇到一些问题如:在映射数据库中的一个C#可空值列时,使用Framework来处理数据库数据时变得相当困难;为了解决这一问题CLR中引入了“C#可空值类型(nullable value type)”
成都创新互联公司网络公司拥有十多年的成都网站开发建设经验,近1000家客户的共同信赖。提供成都网站制作、成都网站设计、外贸营销网站建设、网站开发、网站定制、买链接、建网站、网站搭建、成都响应式网站建设公司、网页设计师打造企业风格,提供周到的售前咨询和贴心的售后服务
为理解它们是如何工作的,先看看CLR中的逻辑:
- [Serializable, StructLayout(LayoutKind.Sequential)]
- public struct Nullable< T> where T : struct
- {
- private Boolean hasValue = false; // 用一个字段落表示装态,初始假定为Null
- internal T value = default(T);
- public Nullable(T value)
- {
- this.value = value;
- this.hasValue = true;
- }
- public bool HasValue { get { return hasValue; } }
- public T Value
- {
- get
- {
- if (!hasValue) throw new InvalidOperationException("Nullable object must have a value.");
- return value;
- }
- }
- public T GetValueOrDefault() { return value; }
- public T GetValueOrDefault(T defaultValue)
- {
- if (!HasValue) return defaultValue;
- return value;
- }
- public override bool Equals(object obj)
- {
- if (!HasValue) return (obj == null);
- if (obj == null) return false;
- return value.Equals(obj);
- }
- public override int GetHashCode()
- {
- if (!HasValue) return 0;
- return value.GetHashCode();
- }
- public override string ToString()
- {
- if (!HasValue) return String.Empty;
- return value.ToString();
- }
- public static implicit operator Nullable< T>(T value)
- {
- return new Nullable< T>(value);
- }
- }
调用和输出:
- static void Main(string[] args)
- {
- Nullable< Int32> x = 5;
- Nullable< Int32> y = null;
- Console.WriteLine("x:HasValue {0}, value = {1}", x.HasValue, x.Value);
- Console.WriteLine("y:HasValue {0}, value = {1}", y.HasValue, y.GetValueOrDefault());
- Console.ReadLine();
- }
- 输出:
- x:HasValue True, value = 5
- y:HasValue False, value = 0
C#中允许使用问号来申明初始化变量(等同于上面代码)如:
Int32? x = 5;
Int32? y = null;
总结一下C#可空值类型对操作符的解释:
a.一元操作符如果操作数为null,结果为null;
b.二元操作符中任何一个为null,结果为null;
c.比较操作符如果两人个操作数都为null,两者相等;如果一个为null,两者不相等;如果两个数都不为null,对值进行比较;
注意:在操作值类型时会生成大量代码,代码类似对基类(Nullable)代码的调用;
- //一元操作符:(+ ++ - -- ! ~)
- x++; // x = 6;
- y--; // y = null;
- //二元操作符:(+ - * / % & | ^ < < >>)
- x = x + 10; // x = 15;
- y = y * 10; // y = null
- // 比较操作符:(== != < > < = >=)
- if (x == null) Console.WriteLine("x is null;"); else Console.WriteLine("x is not null;");
- if (y == null) Console.WriteLine("y is null;"); else Console.WriteLine("y is not null;");
- if (x != y) Console.WriteLine("x = y;"); else Console.WriteLine("x != y;");
- if (x > y) Console.WriteLine("x > y;"); else Console.WriteLine("x < = y;");
当CLR对一个Nullable< T>实例进行装箱时,会检查它是否为null,如果为null,CLR不实际进行装箱操作,并会返回null值;
如果实例不为空,将从类型中取出值,并对其进行装箱如:
- Int32? a = null;
- object o = a; //a 为null
- Console.WriteLine(" o is null = {0}", o == null); // "true"
- Int32? b = 5;
- o = b; //a 为null
- Console.WriteLine(" o's type = {0}", o.GetType()); // "System.Int32" 对可空值类型调用GetType时CLR会采取欺骗手法返回T,而不是Nullable< T>
在应用可空值类型进行拆箱时,CLR会分配内存(这是一个极特殊的行为,在其它所有情况下,拆箱永远不会导致内存的分配),原因在于一个已装箱的值类型不能简单的拆箱为值类型的可空版本,在已装箱的值类型中并不包含Boolean hasValue字段,故在拆箱时CLR必须分配一个Nullable< T>对象,已初始化hasValue = true ,value = 值类型值。这会对应用程序性能造成一定影响。
通过C#可空值类型调用接口方法
- Int32? n = 5;
- Int32 result = ((IComparable)n).CompareTo(5);
- Console.WriteLine(result); // 0;
新闻名称:简介C#可空值类型
浏览地址:http://www.shufengxianlan.com/qtweb/news8/242208.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联