可空值类型(类型后面加问号)

很多时候经常遇到类型后面加问号?如int? i=null,不知道标示什么,其实这是2.0的新语法:可控制类型.

由于一个值类型变量永远不可能为null,而数据库中的一个列是允许值为空的,为了与数据库中的列相对应,CLR引入了可空值类型。

C#中是以问号表示法声明并初始化可空值类型的,如下代码所示:

int? x=5;

int? y=null;

C#允许对可空值类型进行数据转换和转型,示例代码如下:

int? x=5;

int z =(int)x;

可以对可空值类型进行装箱。其规则是:若可空值类型为null,CLR不进行装箱操作并返回null值,若不为null,则进行装箱。示例代码如下:

static void NullToObject()
{
int? b =null;
Object o =b;
Console.WriteLine("o is null={0}",o==null);//结果o is null=Ture
b=5;
o=b;
Console.WriteLine("o’s type={0}",o.GetType());
//结果o’s type=System.Int32
}

这个示例的中如果第一个结果o is null=True,则马上调用o.GetType()的时候将报错。

可以对可空值类型进行拆箱。CLR允许将一个已装箱的值类型T拆箱为一个T或一个Nullable<T>,示例代码如下:

static void ObjectToNull()
{
 Object o =5;
 int? a=(int?)o;
 int b=(int)o;
 Console.WriteLine("a={0},b={1}",a,b);  //结果a=5,b=5
 o=null;
 a=(int?)o;
}

如果在第八行下面添加b=(int)o;这样就会报空引用异常错误。

通过可空值类型来调用GetType()方法,会发现得到的结果是System.Int32类型,而不是Systems.Nullable<Int32>类型。

通过可空值类型调用接口方法时,Nullable没有像Int32一样实现IComparable接口,但CLR允许下面的代码通过编译。

static void NullUseInterface()
{
int? a=5;
int b=((IComparable)a).CompareTo(5); //能通过编译
Console.WriteLine(b);//结果为0
}

单问号---用于给变量设初值的时候,给变量(int类型)赋值为null,而不是0!

表示该变量可以为null,如:int? i=null;而不带问号 int i=0;(不能让i=null)
public int? para = null;
//public int para;如果不注释掉此行,而把上一行注释掉的话,下面会报错!
public int par()
{
    return this.para ?? 0;
} 

除此之外我们还可能遇到双问号。

双问号---用于判断并赋值,判断问号前面的变量是否为null,如果是则把问号后面的值赋给变量,否则把问号前面变量的值赋给变量。

public static int getSum(int? d1, int? d2)
        {
         int temp1 = d1 ?? 1;
         int temp2 = d2 ?? 2;
         return temp1 + temp2;
        }

static void Main(string[] args)
        {
         Console.WriteLine(getSum(null,null));
         Console.WriteLine(getSum(10,20);
       }

运行结果:
    3

    30            

可空值类型详细介绍:

对于一个类型,如果既可以给它分配一个值,也可以给它分配 nullNothingnullptrnull 引用(在 Visual Basic 中为 Nothing)(表示没有任何值),我们就说这个类型是可空的。因此,可空类型可表示一个值,或表示不存在任何值。例如,类似 String 的引用类型就是可空类型,而类似 Int32 的值类型不是可空类型。由于值类型的容量只够表示适合于该类型的值,因此它不可为空;值类型没有表示空值所需的额外容量。

Nullable 类为 Nullable <(Of <(T>)>) 结构提供补充支持。Nullable 类支持获取可空类型的基础类型,对于其基础值类型不支持泛型比较和相等比较运算的可空类型,该类支持对其进行比较和相等比较运算。

方案
根据具体环境,使用可空类型来表示存在或不存在的事物。例如,HTML 标记的某个可选属性可能存在于某一个标记中,但不存在于另一个标记中;或者数据库表的某个可空列可能存在于表的某一行中,但不存在于另一行中。

可将该属性或列表示为类中的一个字段,并可以将该字段定义为值类型。该字段可包含属性或列的所有有效值,但不能提供一个附加值来表示属性或列不存在。在这种情况下,将该字段定义为可空类型而不是值类型。

装箱和取消装箱
在对可空类型进行装箱时,公共语言运行库自动将 Nullable <(Of <(T>)>) 对象的基础值(而不是 Nullable <(Of <(T>)>) 对象本身)装箱。也就是说,如果 HasValue 属性为 true,则将 Value 属性的内容装箱。如果 HasValue 属性为 false,则将 nullNothingnullptrnull 引用(在 Visual Basic 中为 Nothing) 装箱。在对可空类型的基础值进行取消装箱时,公共语言运行库创建一个新的初始化为基础值的 Nullable <(Of <(T>)>) 结构。

时间: 2024-12-16 23:39:55

可空值类型(类型后面加问号)的相关文章

C#中,为什么在值类型后面加问号

在C#中,声明一个值类型或引用类型的变量,无论是否给这个变量赋初值,该变量都有默认值: 比如声明引用类型变量: string a,其等效于string a = null,string的默认值为null.比如声明值类型变量:int a, 其等效于int a = 0,int的默认值为0. 为什么需要让值类型可以为null? 来看需要让值类型为null的场景: 在数据库中,通常值类型允许为null,比如int, decimal, DateTime类型允许为null,而如果C#中对应的值类型不能为nul

解析类型后加问号和双问号

变量定义中类型后带一个问号,意思是这个数据类型是NullAble类型的.用于给变量设初值的时候,给变量(int类型)赋值为null,而不是0! 例子: int? i = 3 等同于Nullable<int> i = new Nullable<int>(3); int?是泛型Nullable<int>的另一种写法. 在定义方法的时候允许传null值: public void AddUser( string name, string password, int ? role

hive原生和复合类型的数据加载和使用

原生类型 原生类型包括TINYINT,SMALLINT,INT,BIGINT,BOOLEAN,FLOAT,DOUBLE,STRING,BINARY (Hive 0.8.0以上才可用),TIMESTAMP (Hive 0.8.0以上才可用),这些数据加载很容易,只要设置好列分隔符,按照列分隔符输出到文件就可以了. 假设有这么一张用户登陆表 CREATE TABLE login ( uid BIGINT, ip STRING ) ROW FORMAT DELIMITED FIELDS TERMINA

CLR via C#深解笔记三 - 基元类型、引用类型和值类型 | 类型和成员基础 | 常量和字段

编程语言的基元类型 某些数据类型如此常用,以至于许多编译器允许代码以简化的语法来操纵它们. System.Int32 a = new System.Int32();  // a = 0 a = 1; 等价于: int a = 1; 这种语法不仅增强了代码的可读性,其生成的IL代码与使用System.Int32时生成的IL代码是完全一致的. 编译器直接支持的数据类型称为基元类型(primitive type).基元类型直接映射到Framework类库(FCL)中存在的类型.如C#中,int直接映射

动态类型 动态绑定 动态加载

1.动态类型运行时才知道,对象的类型,动态类型在编程中非常常见,简单的说就是id类型 比如代理在自定的时候就是,id类型.当前我们有时候自己定的方法,不确定,传进来的是什么类型的对象,我们也id类型,然后在方法内部去确定类型 2.动态绑定 对象被实例化后,就确定的对象类型,也确定了对象的属性和响应方法.这就是动态绑定. 说白也就是对象的确定了后,会绑定对应的属性和方法.那么我们也就可以动态的去给对象添加和实现方法.Class_addMethod 和 Method_setImplementatio

OC 动态类型,动态绑定,动态加载

Objective-C具有相当多的动态特性,基本的,也是经常被提到和用到的有 动态类型(Dynamic typing) 动态绑定(Dynamic binding) 动态加载(Dynamic loading) 动态类型:程序直到执行时才能确定所属的类. id 数据类型id 通用的对象类型,可以存储任意类型的对象,id后面没有号,它本身就是个指针类似于void ,但只可以指向对象类型 静态类型与动态类型 编译期检查与运行时检查 静态类型在编译期就能检查出错误 静态类型声明代码可读性好 动态类型只有在

null类型的字段加1

很高兴今天学到了一种新方法. 数据库中字段类型为Long ,值可能为null,也可能是某一数.因此对该字段数值进行 +1操作时需要判断该值是null还是数值. 同时实现更新操作.具体如下: update content set hits =           case when hits is null          then 1          else hits+1           end          where id= 123456 还有另外一种方式,先判断值,若为nul

Date类型数据的加一天

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); try { if (startDate != null && !startDate.isEmpty()) { Predicate predicate = cb.greaterThanOrEqualTo(root.<Date>get(Customer_.crtTime), sdf.parse(startDate)); predicates.ad

Swift(二,元组,可选类型,类型转化)

一,首先,元组是Swift中特有的,OC中没有元组相关类型,具体怎么用,看下面的例子吧 //1.使用元组来定义一组数据 let infoTuple = ("cjh",18,1.8) let nameTuple = infoTuple.0 print(nameTuple) let count = nameTuple.characters.count //2.1 普通元组的定义方式 let errorMsg = ("error",123) errorMsg.0 //2.