可空类型(Nullable)
我们知道引用类型都可以给赋个值null,表示空引用.而值类型不能赋值null.
值类型和引用类型的区别
要理解为什么这样就得想下给一个变量赋值后内存里是怎么表示的.如果是值类型则直接在stack(堆栈)中分配一块空间.stack是由操作系统去管理的.如果是引用类型的话会保存成两部分.在heap(托管堆)分配一块内存保存变量的实际值,再在stack中分配一块内存保存heap中分配的那块内存的地址.(托管堆,这是由CLR管理的.C#代码为啥叫托管代码呢,因为背后的一些操作托管给CLR去做了嘛).那引用类型赋值为null,表示还没在heap中分配内存,只是在stack中分配一块内存,但里面内容为空,没保存哪块heap的地址.stack中的内存块有多大呢?所有的引用类型在stack中块的大小都一样的.具体大小要看操作系统,32位的系统就是4个字节,64位系统是8个字节.
讲到了值类型有人可能会想到struct这个特殊的例子.如果在struct又有引用类型咋整呢?其实还是一样,在heap中分配一块地址,在stack中分配块保存地址的内存.不过如果是在引用类型,比如你自己申明的一个class,里面的值类型就全部保存在heap中,不会保存到stack的.
言归正传还是说下可空类型.我们知道在数据库中可以把表中某一列的值设为null.如果我们在C#中从数据库获取到了这样的值该怎么处理.一般情况我们会用DBNull来判断下是否为null值,如果是的话会用某个默认的值的替换.但这样还是不太好.最好还是照原样用个啥东东来代表null.于是就有个可空类型Nullable.它除了多了个可以代表null的功能外,其他操作就跟值类型完全一样.所以我们可以把它看成一个一般的类(准确的讲其实是个struct),但是用起来的样子有点像int这样普通的值类型.
比如Nullable<int> a = 123; Nullable b = 456; Nullable c = null; c = a + b;
对Nullable还有种简写形式.我们平时用的其实都是简写形式.Nullable<int> a =123等价于int? a = 123;就是int 后面加个问号.看起来怪怪的.如果要其他的值类型也一样只要后面加个?即可用来表示可空类型了.比如bool? b = true; long? l = null;
不过虽然可空类型也能进行算术运算.但只是可空类型之间.如果和值类型混合必须得做类型转换.
可空类型转换成值类型:int? a = 123; int b = (int)a;//必须显式转换
值类型转换成可空类型:int a = 123; int? b = (int?)a;//也可以隐式转换int?b = a;
类型转换
我们知道C#是强类型的语言.所以类型一旦在声明时确定了是什么类型就只能是什么类型,不能当成其他类型用.如果要当成其他类型用必须要做类型转换.很多时候因为是做了隐式转换所以我们没发现.比如把int的值赋给doubl或float类型.
补充:其实准确的说应该是C# 3.0和之前的版本是强类型系统.但C# 4.0支持动态语言了.就不能算强类型语言了.不过C# 4.0中如果用到了动态语言就用DLR(Dynamic Language Runtime)来支持,而不是用CLR(Common Language Runtime)来支持.
数值类型的转换很方便比如long num = 123L; int a = (int) num;
checked
我们知道每种数值类型表示的范围都不一样.比如byte表示0至255的范围.而int表示的范围大得多.如果把一个大于255的int值转换成byte值时会发生溢出,但默认情况下此时不会报错.只是会得到个错误的值.比如int a = 256; byte by = (byte)a; //此时by的值是0,如果a是257则by会是1
那怎么在发生溢出的时候检查这种错误呢.这里就要用checked了,它的用法很简单.写上checked关键字,然后来个中括号{}把某段代码括住.如果代码块中有溢出就会报错
比如checked
{
int a = 256;
byte by = (byte)a;
}
此时编译不能通过,会出错.如果你用checked括出多代码.里面某一小部分代码你又不想要检查溢出.那就再用unchecked再{}括起来那块代码就行.
explicit,implicit
我们知道C#预定义的类型就可以像这样转换:long num = 123L; int a = (int) num;//(int)它就是用来表示显式转换
那如果是自己定义的类型呢 ,比如某两个class之间要转换咋整呢?
这就得自己写代码来实现了.比如有两个类staff和member
public class Staff
{
public string Name { get; set; }
public int Age { get; set; }
}
public class Member
{
public string Name { get; set; }
public int Age { get; set; }
}
如果要让它们能互相转换得这样写
public class Member
{
public string Name { get; set; }
public int Age { get; set; }
public static explicit operator Member(Staff s) //表示能通过 Member m = (Member) staffInstance;来把一个Staff实例转换成Member类型
{
Member me = new Member();
me.Age = s.Age;
me.Name = s.Age;
return me;
}
public static explicit operator Staff(Member me ) //表示能通过Staff m = (Staff) memberInstance;来把一个Member实例转换成Staff类型
{
Staff st = new Staff();
st.Age = me.Age;
st.Name = me.Name;
}
}
表示转换作用的两函数必须要是static函数,而且要通过operator来表示是个重载函数.另外那两个函数可以放到类Staff或Member中的任一个里面去定义.也可以把两个函数分开,一个类里放一个.但是只能放两类里不能放其他地方去定义
另外explicit是表示显式转换.隐式转换只是把关键这explicit换成implicit就行.
假如上面那样定义了显式转换则可以在代码中这样去用了
Staff ta = new Staff();
ta.Name = "arwen";
ta.Age = 100;
Member me = (Member) ta;
Staff st = (Staff) me;
注意如果有继承关系的类我们就不用再写两个函数让他们能转换.他们可以直接就这样来转换的
分享到:
相关推荐
C# 单问号 ? 与 双问号 ?? ? : 单问号用于对 int,double,bool 等无法直接赋值为 null 的数据类型进行 null 的赋值,意思是这个数据...C# 提供了一个特殊的数据类型,nullable 类型(可空类型),可空类型可以表示其基
用例子的形式详解了Nullable的用法
null与void的区别可以认为void是根本没有,而null是一个空箱子,里面什么都没有。 null值只能赋值给引用类型,这里注意到string也是一种引用类型;引用类型在C中称为“指针”,即存放变量位置的内存空间位置。将变量...
顾名思义,可空类型指的就是某个对象类型可以为空,同时也是System.Nullable结构的实例。可空类型可以表示基础值类型正常范围的值,然后再加上一次null值。当然,也可以被赋值null值。比如Nullable可以被赋值true、...
Nullable,读作“可空的 Int32”,可以被赋值为 -2147483648 到 2147483647 之间的任意值,也可以被赋值为 null 值。Nullable<bool> 可以被赋值为 true 或 false,或 null。在处理数据库和其他包含可能未赋值的元素...
使用javax Nullable注解必须使用的jar包
Laravel开发-laravel-nullable Laravel 5-向模型添加可空列
Laravel开发-nullable 对对象进行链调用,无论对象是否为空
本文主要介绍了.NET中可空值类型的实现原理,具有很好的参考价值。下面跟着小编一起来看下吧
例如,Nullable,读作“可空的 Int32”,可以被赋值为 -2147483648 到 ... 可空类型具有以下特性: ·可空类型表示可被赋值为 null 值的值类型变量。无法创建基于引用类型的可空类型。(引用类型已支持 null 值。)。
但是,利用 C# 定义的一个修饰符,可将一个变量声明为一个可空(nullable)值类型。可空值类型在行为上与普通值类型相似,但可以将一个 null 值赋给它。如下所示: 代码如下:int? a = null; // 合法 当把一个变量...
ELinq 是一个轻量简单易用的开源Linq ORM数据访问组件,支持Nullable类型和枚举类型,支持根据实体类自动建库建表建关系,支持根据数据库通过T4模版自动生成实体代码,对Linq的谓词提供了完美的支持,旨在让绝大部份...
Laravel的可空数据库字段 通常,未分配值的数据库字段默认为null 。 在创建具有外键约束的记录时,这一点尤其重要。 注意,必须将数据库字段配置为允许空值。 如果该字段未配置为允许null,则更新版本MySQL会将值...
1. 空安全性(Null Safety):Kotlin 是空安全的语言,通过类型系统显式区分可为空(nullable)和不可为空(non-nullable)的引用。这样可以避免空指针异常(NullPointerException)。 2. 函数式编程(Functional ...
(GOOD,PASS)LINQ TO DATATABLE OR DATASET 完美解决方案,可排除DATASET不支持System.Nullable错误,并为GRIDVIEW增加空行.txt
为了让.Net中的值类型可以赋值为null,微软特地添加了Nullable类型,也可简写为T?。但是Nullable自身是结构体,也是值类型,那么它是如何实现将null赋值给值类型的呢? 下面通过自定义一个可空值类型来讲解Nullable...
可变参数、不定参数Demo源码,nullable、nonnull、_Nullable 等区别Demo源码。 博客地址: https://dcsnail.blog.csdn.net/article/details/79107962 https://dcsnail.blog.csdn.net/article/details/79230770