在线不卡日本ⅴ一区v二区_精品一区二区中文字幕_天堂v在线视频_亚洲五月天婷婷中文网站

  • <menu id="lky3g"></menu>
  • <style id="lky3g"></style>
    <pre id="lky3g"><tt id="lky3g"></tt></pre>

    C# 中使用泛型約束來限制類型參數(shù)范圍

    定義泛型類型時,可以指定一個或者多個約束來限制泛型參數(shù)的范圍。在實例化一個泛型類型時,若提供的類型不滿足約束要求,編譯器就會報錯。

    new() 約束

    new 約束要求類型參數(shù)必須有公共無參數(shù)構(gòu)造函數(shù),與其它約束一起使用時,new() 約束必須放在最后。因為值類型都具有默認的公共無參構(gòu)造函數(shù),所以所有的值類型都滿足 new() 約束。

    class DataStore where T : new() { public T Data { get; set; } } // int 是值類型,滿足約束 var store = new DataStore();

    struct 約束

    struct 約束要求類型參數(shù)只能是非空值類型,struct 類型不能和 new() 同時使用,原因前面已經(jīng)說過,即所有的值類型自動滿足 new() 約束。

    class DataStore where T : struct { public T Data { get; set; } } // 報錯,因為 string 是引用類型 var store = new DataStore(); // 報錯,因為是可空值類型 var store = new DataStore(); //正確,int 是值類型 var store = new DataStore();

    class 和 class?約束

    class 約束要求類型參數(shù)只能是引用類型,比如類、接口、委托、數(shù)組。在 C# 8.0 即以后,若打開了 nullable 開關(guān),則必須是不可空引用類型。

    class DataStore where T : class { public T Data { get; set; } = default!; } // 報錯,int 不是引用類型 var store = new DataStore(); // 在C#8.0以上打開 nullable 開關(guān)后報錯 // 因為是可空的 var store = new DataStore(); // 正確,string 是不可空引用類型 var store = new DataStore();

    class? 約束和 class 類似,都要求類型參數(shù)必須是引用類型,但對是否是 nullable 沒有要求。

    class DataStore where T : class? { public T Data { get; set; } } // 正確,無論可空或者不可空的引用類型都可以 var store = new DataStore(); // 正確,無論可空或者不可空的引用類型都可以 var store = new DataStore();

    基類約束和接口約束

    BaseClass 約束要求類型參數(shù)必須是指定的基類或者派生自指定的基類。在 C# 8.0 即以后,若打開了 nullable 開關(guān),則必須是不可空的,BaseClass? 則對可空性不做要求,既可以為不可空的,也可以為可空的。

    public class Person { public string Name { get; set; } = string.Empty; } public class Student : Person { public int Score { get; set; } } class DataStore where T : Person { public T Data { get; set; } = default!; } // 錯誤,Person? 為可空類型 // 如需適用可空類型,使用 where T : Person? 約束 var store = new DataStore(); // 正確,Student 派生自 Person var store = new DataStore();

    此外,還有類似的 Interface 和 Interface? 約束,即類型參數(shù)必須實現(xiàn)指定的接口。在 C# 8.0 及以后版本,若打開了 nullable 開關(guān),類型參數(shù)必須不可空,Interface? 則不做要求

    class DataStore where T : IComparable { public T Data { get; set; } = default!; }

    類型參數(shù)作為約束

    where T : U 約束要求類型參數(shù) T 必須是 U 或者 U的子類型。開啟了 nullable 開關(guān)后,兩者的可空性必須相同。

    public class List { public void Add(List items) where U : T }

    notnull約束

    C# 8.0 引入了 notnull 約束, 要求類型參數(shù)必須非空,既可以是非空值類型,也可以是非空引用類型。

    class DataStore where T : notnull { public T Data { get; set; } = default!; } // 錯誤,int? 為可空值類型 var store = new DataStore(); // 錯誤,Person? 為可空引用類型 var store = new DataStore(); // 正確 var store = new DataStore(); // 正確 var store = new DataStore();

    枚舉約束

    從 C# 7.3 開始,C# 允許使用 System.Enum 作為基類約束,用于限制類型參數(shù)為枚舉類型。

    public static IEnumerable GetEnumChoices() where T : System.Enum { var values = Enum.GetValues(typeof(T)); var list = new List(); foreach (int value in values) list.Add((Enum.GetName(typeof(T), value)!, value)); return list; }

    以上代碼定義了一個從枚舉獲取值-名稱對通用方法,Enum 約束讓代碼可以安全調(diào)用 Enum.GetValues 方法,無需額外的代碼來判斷類型是不是枚舉。

    委托約束

    委托約束和枚舉約束一樣,也是一種特殊類型的基類約束,用于限定類型參數(shù)必須為委托。

    public static TDelegate? TypeSafeCombine(this TDelegate source, TDelegate target) where TDelegate : System.Delegate => Delegate.Combine(source, target) as TDelegate;

    通過使用 System.Delegate 約束,上述代碼可以安全地調(diào)用 Delegate.Combine 來合并兩個委托。否則就需要額外的代碼來判斷類型是不是委托。

    鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
    上一篇 2022年7月1日 15:38
    下一篇 2022年7月1日 15:38

    相關(guān)推薦

    聯(lián)系我們

    聯(lián)系郵箱:admin#wlmqw.com
    工作時間:周一至周五,10:30-18:30,節(jié)假日休息