[转]C#中的?和??
原文链接:http://msdn.microsoft.com/zh-tw/library/2cf62fcy%28VS.80%29.aspx
使用可為 Null 的型別 (C# 程式設計手冊)
可為 Null 的型別可以代表基礎型別的所有值,也可以代表另一個 null 值。您可以使用下列其中一種方法宣告可為 Null 的型別:
System.Nullable<T> variable
-或-
T? variable
T 是可為 Null 之型別的基礎型別,T 可以是任何實值型別 (包括 struct,但不能是參考型別)。
何 時該使用可為 null 的型別,可舉一般的布林變數為例,這種變數有兩個可能的值:true 和 false。但沒有值可以代表「未定義」。在許多設計程式的應用程式中,特別是資料庫互動的程式,變數有可能是以未定義的狀態存在。例如,資料庫中的某個 欄位可能包含 true 或 false 值,但也可能不包含任何值。同樣地,參考型別可以設定為 null 表示其並非初始化的。
由於這些值的性質不同,就需要在程式上另做設計,包括使用其他變數存放狀態資訊、使用特殊值等等。可為 null 的型別修飾詞能夠讓 C# 建立表示未定義之值的實值型別 (Value Type) 變數。
任何實值型別都可以當做可為 null 的型別的基礎,例如:
int? i = 10;
double? d1 = 3.14;
bool? flag = null;
char? letter = 'a';
int?[] arr = new int?[10];
可為 null 之型別的每個執行個體 (Instance) 有兩個公用唯讀屬性:
HasValue
HasValue 屬於 bool 型別。當變數包含非 null 的值時,該屬性會設定為 true。
Value
Value 的型別與基礎型別相同。如果 HasValue 為 true,Value 會包含有意義的值。如果 HasValue 為 false,存取 Value 將會擲回 InvalidOperationException。
在這個範例中,會先使用 HasValue 成員測試變數是否包含值,然後才嘗試顯示該值。
int? x = 10;
if (x.HasValue)
{
System.Console.WriteLine(x.Value);
}
else
{
System.Console.WriteLine("Undefined");
}
您也可以使用下列方式測試值:
int? y = 10;
if (y != null)
{
System.Console.WriteLine(y.Value);
}
else
{
System.Console.WriteLine("Undefined");
}
您可以明確使用轉型或使用 Value 屬性,將可為 null 的型別轉換成標準型別。例如:
int? n = null; //int m1 = n; // Will not compile.
int m2 = (int)n; // Compiles, but will create an exception if x is null.
int m3 = n.Value; // Compiles, but will create an exception if x is null.
如果在兩資料型別之間定義了使用者定義轉換,這兩個資料型別的可為 Null 的型別版本也可以使用該轉換。
可為 Null 的型別也可以使用預先定義的一元和二元運算子,以及現有實值型別的任何使用者定義運算子。如果運算元都是 null,這些運算子就會產生 null 值,否則運算子會使用所包含的值計算結果。例如:
int? a = 10;
int? b = null; a++; // Increment by 1, now a is 11.
a = a * 10; // Multiply by 10, now a is 110.
a = a + b; // Add b, now a is null.
使用可為 Null 的型別執行比較時,如果其中一個可為 Null 的型別是 null,比較的評估結果一定會是 false。因此,請千萬不要認為比較結果為 false 時,反之就是 true。例如:
int? num1 = 10;
int? num2 = null;
if (num1 >= num2)
{
System.Console.WriteLine("num1 is greater than or equal to num1");
}
else
{
// num1 is NOT less than num2
}
因為 num2 是 null 導致其中並未包含值,所以上述 else 陳述式中的結果無效。
兩個皆為 null 之可為 Null 的型別,其比較的評估結果將會是 true。
可為 null 的 bool? 型別可包含三種不同的值:true、false 和 null。因此無法在條件中使用,例如使用 if、for 或 while。例如,這個程式碼會出現 編譯器錯誤 CS0266 的編譯失敗:
bool? b = null;
if (b) // Error CS0266.
{
}
因為在條件內容中 null 表示的意義不明確,所以不允許這項動作。可為 Null 的布林值可以明確轉換成 bool 以便在條件中使用,但是如果物件包含 null 值,就會擲回 InvalidOperationException。因此在轉換為 bool 之前先檢查 HasValue 屬性是很重要的。
可為 Null 的布林值類似於 SQL 使用的布林變數型別。為確保 & 和 | 運算子產生的結果與 SQL 的三值布林型別一致,程式提供下列預先定義的運算子:
bool? operator &(bool? x, bool? y)
bool? operator |(bool? x, bool? y)
這些運算子的結果列於下表:
X | y | x&y | x|y |
---|---|---|---|
True |
true |
True |
true |
True |
false |
False |
true |
True |
null |
Null |
true |
False |
true |
False |
true |
False |
false |
False |
false |
False |
null |
False |
null |
Null |
true |
Null |
true |
Null |
false |
False |
null |
Null |
null |
Null |
null |
參考
概念
C# 程式設計手冊
可為 Null 的型別 (C# 程式設計手冊)
[转]C#中的?和??的更多相关文章
- Python开源框架
info:更多Django信息url:https://www.oschina.net/p/djangodetail: Django 是 Python 编程语言驱动的一个开源模型-视图-控制器(MVC) ...
- mapreduce中一个map多个输入路径
package duogemap; import java.io.IOException; import java.util.ArrayList; import java.util.List; imp ...
- Hadoop 中利用 mapreduce 读写 mysql 数据
Hadoop 中利用 mapreduce 读写 mysql 数据 有时候我们在项目中会遇到输入结果集很大,但是输出结果很小,比如一些 pv.uv 数据,然后为了实时查询的需求,或者一些 OLAP ...
- Python中的多进程与多线程(一)
一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...
- .NET Core中的认证管理解析
.NET Core中的认证管理解析 0x00 问题来源 在新建.NET Core的Web项目时选择“使用个人用户账户”就可以创建一个带有用户和权限管理的项目,已经准备好了用户注册.登录等很多页面,也可 ...
- Angular杂谈系列1-如何在Angular2中使用jQuery及其插件
jQuery,让我们对dom的操作更加便捷.由于其易用性和可扩展性,jQuer也迅速风靡全球,各种插件也是目不暇接. 我相信很多人并不能直接远离jQuery去做前端,因为它太好用了,我们以前做的东西大 ...
- 关于CryptoJS中md5加密以及aes加密的随笔
最近项目中用到了各种加密,其中就包括从没有接触过得aes加密,因此从网上各种查,官方的一种说法: 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学 ...
- In-Memory:在内存中创建临时表和表变量
在Disk-Base数据库中,由于临时表和表变量的数据存储在tempdb中,如果系统频繁地创建和更新临时表和表变量,大量的IO操作集中在tempdb中,tempdb很可能成为系统性能的瓶颈.在SQL ...
- SQL Server中的高可用性(2)----文件与文件组
在谈到SQL Server的高可用性之前,我们首先要谈一谈单实例的高可用性.在单实例的高可用性中,不可忽略的就是文件和文件组的高可用性.SQL Server允许在某些文件损坏或离线的情况下,允 ...
- 【.net 深呼吸】序列化中的“引用保留”
假设 K 类中有两个属性/字段的类型相同,并且它们引用的是同一个对象实例,在序列化的默认处理中,会为每个引用单独生成数据. 看看下面两个类. [DataContract] public class 帅 ...
随机推荐
- Sqli-labs less 22
Less-22 本关和less20.less21是一致的,我们可以从源代码中看到这里对uname进行了"uname"的处理,可以构造payload: admin1"and ...
- POJ 2464 Brownie Points II (树状数组,难题)
题意:在平面直角坐标系中给你N个点,stan和ollie玩一个游戏,首先stan在竖直方向上画一条直线,该直线必须要过其中的某个点,然后ollie在水平方向上画一条直线,该直线的要求是要经过一个sta ...
- ***Xcode Interface Builder或Storyboard中可建立那两种连接?
在Xcode Interface Builder或Storyboard中,可建立到输出口(IBOutlet)和操作(方法,IBAction)的连接. IBOutlet are for output C ...
- WCF传输Dataset大数据量 -压缩
由于WCF不能传输DataTable(不能序列化),所以更多项目中都会使用DataSet作为查询集合的首选返回类型,但是由于DataSet会生成很多的状态信息等,所以DataSet体积也会变大,有几种 ...
- UVA 557 Burger 排列组合递推
When Mr. and Mrs. Clinton's twin sons Ben and Bill had their tenth birthday, the party was held at t ...
- android自动化环境搭建
android自动化环境安装指南 1.appium相关安装(eclipse下)见http://www.cnblogs.com/wangcp-2014/p/5717589.html参考selenium的 ...
- Spring REST for DELETE Request Method Not Supoorted
http://stackoverflow.com/questions/22055251/sending-data-with-angularjs-http-delete-request I have a ...
- MySQL数据库的基本操作命令
MySQL数据库的基本操作命令 [mysql]mysql 常用建表语句 一.mysql服务操作 net start mysql //启动mysql服务 net stop mysql //停止mysql ...
- iOS 开发--NSMutableArray使用枚举方法
可变数组也可以使用枚举方法, 我们在这里提供了两种枚举方法, 一个是正序枚举, 一个是倒序枚举, 在正序枚举中, 元素的个数和顺序都是不可以修改的, 但是在倒序枚举中却可以修改, 这有些耐人寻味. 涉 ...
- wordpress模块无法拖拽/显示选项点击无反应
问题:wordpress模块无法拖拽/显示选项点击无反应,还有编辑器的全屏什么的都用不了,按F12查看了console,提示很多jQuery is not defined... 解决方法:把wp-in ...