C#变量定义中含问号的用法

简介:   C#变量定义中含问号的用法 收藏 public Color? TextColor { get { return _textColor; } set { _textColor = value; } }今天看程序代码,发现Color? TextColor 这个属性的申明,感觉很不能理解,后来在google上搜索了一下,原来这是vs2005开始c#新有的特性,具体的说也可以是C#2.0的新特性。

  C#变量定义中含问号的用法 收藏 public Color? TextColor { get { return _textColor; } set { _textColor = value; } } 今天看程序代码,发现Color? TextColor 这个属性的申明,感觉很不能理解,后来在google上搜索了一下,原来这是vs2005开始c#新有的特性,具体的说也可以是C#2.0的新特性。 下面是我搜索到得相关描述: Nullable Types in C# One of the "late breaking" features in C# 2.0 is what is known as "Nullable Types". The details can be found in the C# 2.0 language spec. Nullable types address the scenario where you want to be able to have a primitive type with a null (or unknown) value. This is common in database scenarios, but is also useful in other situations. In the past, there were several ways of doing this: A boxed value type. This is not strongly-typed at compile-time, and involves doing a heap allocation for every type. A class wrapper for the value type. This is strongly-typed, but still involves a heap allocation, and the you have to write the wrapper. A struct wrapper that supports the concept of nullability. This is a good solution, but you have to write it yourself. To make this easier, in VS 2005, we're introducing a new type named "Nullable", that looks something like this (it's actually more complex than this, but I want to keep the example simple): struct Nullable<T> { public bool HasValue; public T Value; }You can use this struct directly, but we've also added some shortcut syntax to make the resulting code much cleaner. The first is the introduction of a new syntax for declaring a nullable type. Rather than typing: Nullable<int> x = new Nullable<int>(125);I can write: int? x = 125;which is much simpler. Similarly, rather than needed to write a null test as: if (x.HasValue) {...}you can use a familiar comparison to null: if (x != null) {...}Finally, we have support to make writing expressions easier. If I wanted to add two nullable ints together and preserve null values, if I didn't have language support, I would need to write: Nullable<int> x = new Nullable<int>(125); Nullable<int> y = new Nullable<int>(33); Nullable<int> z = (x.HasValue && y.HasValue) ? new Nullable<int>(x.Value + y.Value) : Nullable<int>.NullValue;At least I think that's what I'd have to write - it's complex enough that I'm not sure this code works. This is ugly enough that it makes using Nullable without compiler support a whole lot of work. With the compiler support, you write: int? x = 125; int? y = 33; int? z = x + y;而后又惊异发现居然还有??操作符的存在,感叹原来自己已经落后不止一个时代,也一并贴个用法于下: The ?? operator returns the left-hand operand if it is not null, or else it returns the right operand.A nullable type can contain a value, or it can be undefined. The ?? operator defines the default value to be returned when a nullable type is assigned to a non-nullable type. If you try to assign a nullable type to a non-nullable type without using the ?? operator, you will generate a compile-time error. If you use a cast, and the nullable type is currently undefined, an InvalidOperationException exception will be thrown. // nullable_type_operator.cs using System; class MainClass { static int? GetNullableInt() { return null; } static string GetStringValue() { return null; } static void Main() { // ?? operator example. int? x = null; // y = x, unless x is null, in which case y = -1. int y = x ?? -1; // Assign i to return value of method, unless // return value is null, in which case assign // default value of int to i. int i = GetNullableInt() ?? default(int); string s = GetStringValue(); // ?? also works with reference types. // Display contents of s, unless s is null, // in which case display "Unspecified". Console.WriteLine(s ?? "Unspecified"); } } 下面一片是摘自于dashang 的中文讲解。原文地址(http://blog.chinaitlab.com/user1/370055/archives/2006/45231.html) 随着C#语言最新标准的出炉,现在它也提供了对可空类型的支持。这个小变化将会在处理那些包括可选项的数据库记录时非常有用。当然在其他地方,它也是非常有用的。  简单说来,可空数据类型就是包含了所定义的数据类型或者值的空(null)的类型。C#的ECMA-334标准提供了对所有C#值类型的可空版本的描述。   定义可空类型  定义可空类型和非可空类型基本类似,不同的是采用了?来表示。如定义一个整型,你可以使用简单的语句:int myInt = 1;   为了使得myInt能够存储一个空值,你可以这样声明它:int? myNullableInt = 1;   你可以看到,这两个变量看上去好像是一样的。但是,可空类型的版本是非常不同的。可空的版本事实上是一个结构,它将值类型和一个标记该值是否为空的标志位结合在一起。一个可空类型有两个公共可读的属性,HasValue和value。如果存储了一个值那么HasValue这个布尔型变量就为true。否则,如果变量是空值就是false。如果HasValue是true,你可以获取这个变量的值。如下有两个对可空变量的有效赋值:double? myDouble = 3.1415926;double? myOtherDouble = null;   你可以看到,myDouble被赋值了,但是也可以被赋为空。在第二个语句里,myOtherDouble被初始化一个空值,这在一个非可空类型里不能这样做的。  使用可空类型  可空类型可以像普通值类型一样的使用。事实上,可以使用内建的隐式转换来转换相同类型的可空变量和非可空变量。这意味着你可以在一个标准整型和可空整型之间相互转换:int? nFirst = null;int Second = 2;nFirst = Second; // 有效nFirst = 123; // 有效Second = nFirst; // 同样有效nFirst = null; // 有效Second = nFirst; // 例外,后者是非空类型   在以上的语句里,你可以看到如果可空变量不包含空值的话是可以和非可空变量交换值的。如果它是一个空值,那么就会抛出例外。为了防止例外,你可以使用可空变量的HasValue属性:if (nFirst.HasValue) Second = nFirst;   你可以看到,如果nFirst有值赋值就会发生,否则程序会跳过此句语句。  使用可空类型的操作符  虽然可以使用相同值类型的可空和非可空变量的转换,也必须对操作符进行一些改变使得它们可以处理可空和非可空值。这些操作符被称为提升的操作符。  考虑如下代码:int ValA = 10;int? ValB = 3;int? ValC = ValA * ValB;   在ValC里存储了什么?ValC中存储了30。标准操作符被扩展使得它们能够处理可空类型。考虑到如下的变化:int ValA = 10;int? ValB = null;int? ValC = ValA * ValB;   ValC这次值为多少?ValC为空。无论哪个操作数为空,提升的操作符的结果为空。即使进行加法或减法,结果也为空。  如果ValC不为可空类型呢?如下的代码会有什么样的结果?int ValA = 10;int? ValB = null;int ValC = ValA * ValB; // ValC 不为可空类型   代码将会抛出一个异常。ValA*ValB结果为空,但是不能赋值为非可空类型,这将会导致程序异常的抛出。比较  比较将会和数学计算操作类似的方式处理。比较的操作数将同时被提升为可空的。这样就可以比较了,如果某个操作数为空,那么比较结果为false。  如果对比是否相等,两个同为空的变量将被认为是相等的。一个空变量和其他任意值的变量相比的结果是不相等。下面是一些比较的例子:int abc = 123;int xyz = 890;int? def = null;int? uvw = 123;Comparison Resultabc == xyz // falseabc == def // falsedef == null // trueabc == uvw // trueuvw == null // falseuvw != null // true   在所有的比较中,结果都是布尔型值true或者false。在做大小比较的时候,如果操作数的任意一个或者都是空值,那么结果返回的是false。如下展示了一些例子: Comparison Resultabc > uvw // false, they are equalabc < def // false, def is nulluvw < def // false, because def is nulldef > null // false, because right side is nulluvw > null // false, because right side is null   可空性的移去  C#在新版本中加入了一个新的操作符,它被称为空接合操作符,使用如下的格式:returnValue = first second;   这样,如果first不为空,那么它的值将返回作为returnValue的值。如果first为空,那么second的值将被返回。注意:returnValue可以为可空变量或者非可空变量。   如果你希望可空变量的值到一个非可空的版本,你可以这样做:int? ValA= 123;int? ValB = null;int NewVarA = ValA ?? -1;int NewVarB = ValB ?? -1;   NewVarA的值将会为123因为ValA不是空值。NewVarb的值是-1因为ValB是空值。你看一看到,这里你将可以将变量从一个空值转化成一个缺省值。这里缺省值是-1。  结束语  总得来说,最新的C#允许一个可空类型的存在。语言内部建立了对可空类型的处理机制。可空类型使得数据库记录和其他可选信息更加的容易处理 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/jlp001/archive/2009/07/29/4389390.aspx

目录
相关文章
|
安全 C#
C# List基本用法
C# List基本用法
|
存储 C# 索引
C# 一分钟浅谈:变量与数据类型简介
【9月更文挑战第1天】在 C# 编程中,了解变量与数据类型至关重要。本文详细介绍了 C# 中的值类型(如整数、浮点数、布尔值等)和引用类型(如类、接口、数组、字符串)。通过示例代码展示了变量的声明与使用方法,并针对数据类型转换错误、变量未初始化及数值溢出等常见问题提供了解决方案。正确选择数据类型不仅能提升程序性能,还可避免潜在错误,有助于编写高质量代码。
317 47
C# Hashtable的用法
哈希表(HashTable)是一种通过键值对直接访问的数据结构。Add 方法用于添加成员,先检查成员是否已存在,若不存在则计算其 ASCII 码值作为散列值并添加到表中。Remove 方法用于移除成员,Size 方法返回集合成员数量。代码实现了这些功能,确保集合操作的高效性。
|
存储 安全 编译器
学懂C#编程:属性(Property)的概念定义及使用详解
通过深入理解和使用C#的属性,可以编写更清晰、简洁和高效的代码,为开发高质量的应用程序奠定基础。
1093 12
|
安全 C# 索引
C#一分钟浅谈:属性与索引器的定义
本文深入浅出地介绍了C#编程中的属性和索引器。属性让字段更安全,通过访问器方法在读写时执行额外操作,如验证数据有效性;索引器则赋予类数组般的访问方式,支持基于索引的数据访问模式。文章通过示例代码展示了如何定义及使用这两种特性,并提供了常见问题及其解决方案,帮助读者写出更健壮、易维护的代码。希望读者能从中学习到如何有效利用属性和索引器增强C#类的功能性。
349 12
|
C#
c#中switch case语句的用法
C#中的 `switch case`语句提供了一种简洁而高效的方式来处理多个条件分支。通过了解其基本语法、注意事项和高级用法,可以在实际开发中灵活运用 `switch case`,提高代码的可读性和维护性。希望本文能帮助你更好地理解和使用C#中的 `switch case`语句。
1279 0
|
存储 C# 开发者
C# 编程基础:注释、变量、常量、数据类型和自定义类型
C# 编程基础:注释、变量、常量、数据类型和自定义类型
195 1
|
传感器 开发框架 JSON
聊聊 C# dynamic 类型,并分享一个将 dynamic 类型变量转为其它类型的技巧和实例
聊聊 C# dynamic 类型,并分享一个将 dynamic 类型变量转为其它类型的技巧和实例
722 0