`
lovnet
  • 浏览: 6713303 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

可空类型Nullable,类型转换checked,explicit,implicit

 
阅读更多

可空类型(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# 可空类型(Nullable)

    C# 单问号 ? 与 双问号 ?? ? : 单问号用于对 int,double,bool 等无法直接赋值为 null 的数据类型进行 null 的赋值,意思是这个数据...C# 提供了一个特殊的数据类型,nullable 类型(可空类型),可空类型可以表示其基

    Nullable转换问题

    用例子的形式详解了Nullable的用法

    C#难点逐个击破(8):可空类型System.Nullable

    null与void的区别可以认为void是根本没有,而null是一个空箱子,里面什么都没有。 null值只能赋值给引用类型,这里注意到string也是一种引用类型;引用类型在C中称为“指针”,即存放变量位置的内存空间位置。将变量...

    C# 可空类型的具体使用

    顾名思义,可空类型指的就是某个对象类型可以为空,同时也是System.Nullable结构的实例。可空类型可以表示基础值类型正常范围的值,然后再加上一次null值。当然,也可以被赋值null值。比如Nullable可以被赋值true、...

    C# 可空类型分析(含程序代码)

    Nullable,读作“可空的 Int32”,可以被赋值为 -2147483648 到 2147483647 之间的任意值,也可以被赋值为 null 值。Nullable&lt;bool&gt; 可以被赋值为 true 或 false,或 null。在处理数据库和其他包含可能未赋值的元素...

    javax Nullable 标签的jar

    使用javax Nullable注解必须使用的jar包

    Laravel开发-laravel-nullable

    Laravel开发-laravel-nullable Laravel 5-向模型添加可空列

    Laravel开发-nullable

    Laravel开发-nullable 对对象进行链调用,无论对象是否为空

    .NET中可空值类型【Nullable&lt;T&gt;】实现原理

    本文主要介绍了.NET中可空值类型的实现原理,具有很好的参考价值。下面跟着小编一起来看下吧

    C# 可空类型分析

    例如,Nullable,读作“可空的 Int32”,可以被赋值为 -2147483648 到 ... 可空类型具有以下特性: ·可空类型表示可被赋值为 null 值的值类型变量。无法创建基于引用类型的可空类型。(引用类型已支持 null 值。)。

    浅谈C# 中的可空值类型 null

    但是,利用 C# 定义的一个修饰符,可将一个变量声明为一个可空(nullable)值类型。可空值类型在行为上与普通值类型相似,但可以将一个 null 值赋给它。如下所示: 代码如下:int? a = null; // 合法 当把一个变量...

    ELinq 是一个轻量简单易用的开源Linq ORM数据访问组件,支持Nullable类型和枚举类型.zip

    ELinq 是一个轻量简单易用的开源Linq ORM数据访问组件,支持Nullable类型和枚举类型,支持根据实体类自动建库建表建关系,支持根据数据库通过T4模版自动生成实体代码,对Linq的谓词提供了完美的支持,旨在让绝大部份...

    laravel-nullable-field:自动为laravel中的空字段设置空值

    Laravel的可空数据库字段 通常,未分配值的数据库字段默认为null 。 在创建具有外键约束的记录时,这一点尤其重要。 注意,必须将数据库字段配置为允许空值。 如果该字段未配置为允许null,则更新版本MySQL会将值...

    kotlin学习项目案例

    1. 空安全性(Null Safety):Kotlin 是空安全的语言,通过类型系统显式区分可为空(nullable)和不可为空(non-nullable)的引用。这样可以避免空指针异常(NullPointerException)。 2. 函数式编程(Functional ...

    (GOOD,PASS)LINQ TO DATATABLE OR DATASET 完美解决方案,可排除DATASET不支持System.Nullable错误,并为GRIDVIEW增加空行

    (GOOD,PASS)LINQ TO DATATABLE OR DATASET 完美解决方案,可排除DATASET不支持System.Nullable错误,并为GRIDVIEW增加空行.txt

    .NET中可空值类型【NullableT】实现原理

    为了让.Net中的值类型可以赋值为null,微软特地添加了Nullable类型,也可简写为T?。但是Nullable自身是结构体,也是值类型,那么它是如何实现将null赋值给值类型的呢? 下面通过自定义一个可空值类型来讲解Nullable...

    可变参数、不定参数和nullable、nonnull

    可变参数、不定参数Demo源码,nullable、nonnull、_Nullable 等区别Demo源码。 博客地址: https://dcsnail.blog.csdn.net/article/details/79107962 https://dcsnail.blog.csdn.net/article/details/79230770

Global site tag (gtag.js) - Google Analytics