亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C#基礎語法:可空類型詳解

2020-01-24 01:41:51
字體:
來源:轉載
供稿:網友

以下是System.Nullable<T>在FCL中的定義。

[Serializable, StructLayout(LayoutKind.Sequential)]public struct Nullable<T> where T :struct{ private Boolean hasValue= false; internal T value= default(T);public Nullable(T value) {this.value= value;this.hasValue= true; }public Boolean HasValue {get {return hasValue; } }public T Value {get  {  if (!hasValue)    {   throw new InvalidOperationException("Nullable object must have a value.");    }   return value;  } }public T GetValueOrDefault() {return value; }public T GetValueOrDefault(T defaultValue) {if(!HasValue)return defaultValue;return value; }public override Boolean Equals(object other) {if(!HasValue)return (other== null);if(other== null)return false;return value.Equals(other); }public override int GetHashCode() {if(!HasValue)return 0;return value.GetHashCode(); }public override string ToString() {if(!HasValue)return "";return value.ToString(); }public static implicit operator Nullable<T>(T value) {return new Nullable<T>(value); }}

可以看出 null 的類型的每個實例都具有兩個公共的只讀屬性:

1.HasValue

HasValue 屬于 bool 類型。當變量包含非 null 值時,它被設置為 true。

2.Value

Value 的類型與基礎類型相同。如果 HasValue 為 true,則說明 Value 包含有意義的值。如果 HasValue 為 false,則訪問 Value 將引發 InvalidOperationException。

那么我們怎么定義可空類型?

null 的類型可通過下面兩種方式中的一種聲明:

復制代碼 代碼如下:

System.Nullable<T> variable

- 或 -

T? variable


T 是可以為 null 的類型的基礎類型。T 可以是包括 struct 在內的任何值類型;但不能是引用類型。

現在舉一個例子,運用一下看看效果是不是一樣。

Console.WriteLine("========可空類型操作演示========/n");      Console.WriteLine("/n=========Nullable<T>===========/n");      Nullable<int> x = 5;      Nullable<bool> y = false;      Nullable<double> z = 5.20;      Nullable<char> n = null;      Console.WriteLine("x.HasValue={0},   x.Value={1}",x.HasValue,x.Value);      Console.WriteLine("y.HasValue={0},   y.Value={1}", y.HasValue, y.Value);      Console.WriteLine("z.HasValue={0},   z.Value={1}", z.HasValue, z.Value);      Console.WriteLine("n.HasValue={0},   n.Value={1}",n.HasValue, n.GetValueOrDefault());      Console.WriteLine("/n============== T? ============/n");      int? X = 5;      bool? Y = false;      double? Z = 5.20;      char? N = null;      int?[] arr ={1,2,3,4,5};//一個可空類型的數組      Console.WriteLine("X.HasValue={0},   X.Value={1}", X.HasValue,X.Value);      Console.WriteLine("y.HasValue={0},   Y.Value={1}", Y.HasValue, Y.Value);      Console.WriteLine("Z.HasValue={0},   Z.Value={1}", Z.HasValue, Z.Value);      Console.WriteLine("N.HasValue={0},   N.Value={1}", N.HasValue, N.GetValueOrDefault());      Console.WriteLine("/n================================/n");      Console.ReadKey();

可空類型可強制轉換為常規類型,方法是使用強制轉換來顯式轉換或者通過使用 Value 屬性來轉換。從普通類型到可以為 null 的類型的轉換是隱式的。例如:

復制代碼 代碼如下:

int? a = 5;//int--->int?
double? b = a; //int?---->double?
int? c = (int?)b;//double?---int?
int d = (int)c;//int?---->int  不能隱式轉換例如int d=c;則不能編譯
int? e = null;
int f = e.Value;//可以編譯但是會提示異常引發 InvalidOperationException

可空類型還可以使用預定義的一元和二元運算符(提升運算符),以及現有的任何用戶定義的值類型運算符。如果操作數為 null,這些運算符將產生一個 null 值;否則運算符將使用包含的值來計算結果。例如:

復制代碼 代碼如下:

int? a = 10;
int? b = null;
//一元操作符(+ ++  -- = - ! ~)
a++;        //a=11;
//二元操作符(+ - * / % & | ^ << >>) 
a *= 10;   //a=110;
//a = a + b;  //now a is null
//相等性操作符(== !=) 
if (b == null)
{
    b=b.GetValueOrDefault();
}
Console.WriteLine(a.Value);
a = a + b;
/*  if(a == null) ...  
* if(b == null) ...  
* if(a != b) ... */
//比較操作符 
if (a > b)
{
    Console.WriteLine("a>b");
}

下面總結下C#如何對操作符的用法:
  1. 一元操作符(+ ++ - -- ! ~)。如果操作數為null,結果為null。

  2. 二元操作符(+ - * / % | ^ << >>)。兩個操作數中任何一個為null,結果為null。

  3. 相等性操作符(== !=)。如果兩個操作數都為null,兩者相等。如果一個操作數為null,則兩者不相等。如果兩個操作數都不為null,就對值進行比較,判斷它們是否相等。

  4. 比較操作符(< > <= >=)。兩個操作數中任何一個為null,結果為false。如果兩個操作數都不為null,就對值進行比較。

至此我在對上面代碼的a=a+b解釋一下,它實際等價于:

復制代碼 代碼如下:

a = a.HasValue && b.HasValue ? a.Value + b.Value : (int?)null;

在操縱可空實例時,會生成大量代碼,如以下方法:

復制代碼 代碼如下:

privatestaticint? NullableCodeSize(int? a, int? b)
{
    return a + b;
}

編譯這個方法時,編譯器生成的IL代碼等價于以下的C#代碼:
復制代碼 代碼如下:

privatestatic Nullable<int> NullableCodeSize(Nullable<int> a, Nullable<int> b)
{
Nullable<int> nullable1 = a;
Nullable<int> nullable2 = b;
if(!(nullable1.HasValue & nullable2.HasValue))
returnnew Nullable<int>();
else
returnnew Nullable<int>(nullable1.GetValueOrDefault() + nullable2.GetValueOrDefault());
}

??運算

假如左邊的操作數不為null,就返回這個操作數的值。如果左邊的操作數為null,就返回右邊的操作數的值。利用空接合操作符,可方便地設置變量的默認值??战雍喜僮鞣囊粋€好處在于,它既能用于引用類型,也能用于可空值類型。如下所示:

復制代碼 代碼如下:

//===========可空類型=========
int? b =null;
int a = b ??520;
等價于:

//a = b.HasValue ? b.Value : 520
Console.WriteLine(x); //print:"520"
//===========引用類型=========
String s = GetstringValue();
String s= s ??"Unspecified";


等價于:
復制代碼 代碼如下:

//String s = GetstringValue();
//filename = (s != null) ? s : "Unspecified";

裝箱和拆箱轉換

   假定有一個Nullable<int>變量,它被邏輯上設為null。假如將這個變量傳給一個方法,而該方法期望的是一個object,那么必須對這個變量執行裝箱,并將對已裝箱的Nullable<int>的一個引用傳給方法。但并不是一個理想的結果,因為方法現在是作為一個非空的值傳遞的,即使Nullable<int>變量邏輯上包含null值。為解決這個問題,CLR會在對一個可空變量裝箱的時候執行一些特殊代碼,以維護可空類型在表面上的合法地位。

具體地說,當CLR對一個Nullable<T>實例進行裝箱時,它會檢查它是否為null。如果是,CLR實際就不進行任何裝箱操作,并會返回null值。如果可空實例不為null,CLR就從可空實例中取出值,并對其進行裝箱。也就是說,一個值為5的Nullable<int>會裝箱成值為5的一個已裝箱Int32。如下所示:

復制代碼 代碼如下:

//對Nullable<T>進行裝箱,要么返回null,要么返回一個已裝箱的T
int? n =null;
object o = n; //o為null
Console.WriteLine("o is null={0}", o ==null); //"true"

n =5;
o = n; //o引用一個已裝箱的int
Console.WriteLine("o's type={0}", o.GetType()); //"System.Int32"

CLR允許將一個已裝箱的值類型T拆箱為一個T,或者一個Nullable<T>。假如對已裝箱值類型的引用是null,而且要把它拆箱為Nullable<T>,那么CLR會將Nullable<T>的值設為null。以下代碼對這個行為進行了演示:

復制代碼 代碼如下:

//創建一個已裝箱的int
object o =5;

//把它拆箱為一個Nullable<int>和一個int
int? a = (int?)o; //a=5
int b = (int)o; //b=5

//創建初始化為null的一個引用
o =null;

//把它“拆箱”為一個Nullable<int>和一個int
a = (int?)o; //a=null;
b = (int)0; //拋出NullReferenceException

將一個值類型拆箱為值類型的一個可空的版本時,CLR可能必須分配內存。這是極其特殊的一個行為,因為在其他所有情況下,拆箱永遠不會導致內存的分配。原因在于一個已裝箱的值類型不能簡單的拆箱為值類型的可空版本,在已裝箱的值類型中并不包含 hasValue字段,故在拆箱時CLR必須分配一個Nullable< T>對象,以初始化hasValue = true ,value = 值類型值。
調用接口方法

  下面的代碼中,將一個Nullable<int>類型的變量n轉型為一個IComparable<int>,也就是一個接口類型。然而,Nullable<T>不像int那樣實現了IComparable<int>接口。C#編譯器允許這樣的代碼通過編譯,且CLR的校驗器會認為這樣的代碼是可驗證的,從而允許我們使用這種更簡潔的語法:

復制代碼 代碼如下:

int? n =5;
int result = ((IComparable)n).CompareTo(5); //能順利編譯和運行
Console.WriteLine(result);

  如果CLR沒有提供這一特殊支持,那就必須對已拆箱的值類型進行轉型,然后才能轉型成接口以發出調用:
復制代碼 代碼如下:

int result = ((IComparable)(int)n).CompareTo(5);

可以使用 C# typeof 運算符來創建表示可以為 null 的類型的 Type 對象:

復制代碼 代碼如下:

System.Type type = typeof(int?);

還可以使用 System.Reflection 命名空間的類和方法來生成表示可以為 null 的類型的 Type 對象。但是,如果您試圖使用 GetType 方法或 is 運算符在運行時獲得可以為 null 的類型變量的類型信息,得到的結果是表示基礎類型而不是可以為 null 的類型本身的 Type 對象。

如果對可以為 null 的類型調用 GetType,則在該類型被隱式轉換為 Object 時將執行裝箱操作。因此,GetType 總是返回表示基礎類型而不是可以為 null 的類型的 Type 對象。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩欧美在线看| 亚洲精品一二区| 国产精品久久77777| 日韩激情在线视频| 国产精品久久91| 欧美性色视频在线| 在线看片第一页欧美| 国产日韩精品入口| 久久久成人精品| 中文字幕一精品亚洲无线一区| 中文字幕欧美精品日韩中文字幕| 久久综合免费视频影院| www国产精品视频| 午夜精品99久久免费| 国语自产在线不卡| 亚洲自拍欧美色图| 国产极品jizzhd欧美| 色偷偷噜噜噜亚洲男人的天堂| 国产精品免费视频xxxx| 2023亚洲男人天堂| 一区二区三区四区在线观看视频| 麻豆乱码国产一区二区三区| 97精品在线视频| 欧美激情在线狂野欧美精品| 日韩av电影在线免费播放| 精品欧美aⅴ在线网站| 日韩视频在线免费| 国产成人av网| 91久久综合亚洲鲁鲁五月天| 色偷偷偷综合中文字幕;dd| 久久久伊人欧美| 欧美激情在线一区| 国产精品精品一区二区三区午夜版| 国产一区二区在线免费| 久久久久久久久久久免费| 夜夜嗨av色一区二区不卡| 日韩欧美亚洲综合| 午夜精品福利电影| 亚洲xxxx视频| 在线精品国产欧美| 亚洲已满18点击进入在线看片| 欧美壮男野外gaytube| 国产一区二区在线免费视频| 欧美精品videos另类日本| 亚洲曰本av电影| 欧美一区二区三区……| 欧美人交a欧美精品| 成人免费观看网址| 国产v综合ⅴ日韩v欧美大片| 亚洲一区二区三区成人在线视频精品| 国产一区二区久久精品| 91精品久久久久久| 在线观看中文字幕亚洲| 国产亚洲精品成人av久久ww| 欧美性69xxxx肥| 成人免费大片黄在线播放| 国产精品成久久久久三级| 精品国产欧美一区二区五十路| 日本三级韩国三级久久| 日韩成人中文字幕| 国产成人精品一区二区在线| 久久久久久久影视| 国产精品电影在线观看| 91深夜福利视频| 怡红院精品视频| 日本久久精品视频| 亚洲天堂男人的天堂| 成人黄色av网站| 国模精品视频一区二区| 欧美性受xxx| 成人美女免费网站视频| 国产精品国模在线| 日韩精品电影网| 欧美xxxx做受欧美.88| 国产精品九九久久久久久久| 亚洲精品久久久一区二区三区| 插插插亚洲综合网| 精品国偷自产在线视频99| 在线视频欧美性高潮| 97在线观看免费高清| 国产成人jvid在线播放| 亚洲人成毛片在线播放| 国产精品一区二区三区毛片淫片| 亚洲va欧美va在线观看| 亚州av一区二区| 亚洲综合中文字幕在线观看| 久久国产精品久久久久| 国产视频久久久| 欧美高清在线视频观看不卡| 亲子乱一区二区三区电影| 国产美女精彩久久| 51视频国产精品一区二区| 欧美成人午夜免费视在线看片| 国产精品视频1区| 国产亚洲欧洲高清一区| 欧美在线视频免费观看| 亚洲字幕在线观看| 97成人超碰免| 亚洲欧美成人在线| 91精品在线播放| 国产精品国产亚洲伊人久久| 亚洲乱码一区av黑人高潮| 国产精品视频网| 亚洲人成电影网站色xx| 一本一本久久a久久精品牛牛影视| 亚洲欧美综合图区| 亚洲天堂视频在线观看| 在线视频中文亚洲| 成人美女av在线直播| 亚洲一区二区三| 国产九九精品视频| 亚洲图片在线综合| 日韩精品免费看| 国产一区二区三区久久精品| 91经典在线视频| 欧美在线视频a| 国产午夜精品一区二区三区| 欧美另类xxx| 久久久久久久999精品视频| 国产一区二区在线免费| 日韩av男人的天堂| 久久影视电视剧凤归四时歌| 国产欧美最新羞羞视频在线观看| 日韩欧美一区二区在线| 日韩欧美精品在线观看| 91精品国产免费久久久久久| 国产亚洲精品激情久久| 69久久夜色精品国产7777| 国产亚洲欧美另类中文| 国产精品69av| 米奇精品一区二区三区在线观看| 啪一啪鲁一鲁2019在线视频| 精品女厕一区二区三区| 日韩亚洲欧美成人| 亚洲香蕉成视频在线观看| 国产女精品视频网站免费| 日韩美女福利视频| 亚洲第一天堂无码专区| 成人午夜高潮视频| 亚洲激情第一页| 国产精品一区二区久久精品| 欧美精品在线免费播放| 亚洲第一视频在线观看| 亚洲美女av电影| 亚洲男人天堂手机在线| 亚洲欧美在线免费| 日韩av色在线| 成人写真福利网| 国产成人精品在线观看| 久久视频在线免费观看| 久久久久久亚洲精品不卡| 青青草原一区二区| 亚洲午夜性刺激影院| 日韩精品欧美激情| 日本韩国欧美精品大片卡二| 日韩成人av在线播放| 欧美极品美女视频网站在线观看免费| 久久久精品久久久久| 国产精品视频久久久| 亚洲福利视频久久| 国产精自产拍久久久久久蜜| 欧美高清不卡在线| 韩国一区二区电影| 欧美精品免费在线|