C# Where 泛型約束的實現(xiàn)
在C#中,Where關(guān)鍵字主要有兩種用途
1、在泛型約束中限制類型參數(shù)
2、在LINQ查詢中篩選數(shù)據(jù)
本文主要介紹where關(guān)鍵字在在泛型約束中的使用
泛型定義中的 where
子句指定對用作泛型類型、方法、委托或本地函數(shù)中類型參數(shù)的參數(shù)類型的約束。通過使用 where
關(guān)鍵字和泛型約束,可以創(chuàng)建更安全、更靈活的泛型類和方法的實現(xiàn)。
使用的對象
Where可以對類、方法、委托和接口使用。
類的使用,例如C#中常用的List<T>
方法的使用,
public void MyFunc<T>() where T:struct
委托的使用
public delegate void MyDelete<T>() where T : class;
接口的使用
約束分類
約束 | 說明 |
where T : struct | T必須是值類型,如int,double等 |
where T : class | T必須是引用類型,如string,List<T>等 |
where T : new() | T必須有無參構(gòu)造函數(shù),即T參數(shù)可以通過使用new關(guān)鍵字創(chuàng)建實例。當與其他約束一起使用時,new() 約束必須最后指定。 |
where T : 基類 | T 必須繼承自某個基類 |
where T : 接口 | T 必須實現(xiàn)某個接口 |
where T : U | T 必須派生自 U |
where T : struct
public class MyClass<T> where T : struct { public T Value { get; set; } }
例子:
// 只接受值類型的泛型方法 public class ValueCalculator<T> where T : struct { public T Add(T a, T b) { return (dynamic)a + (dynamic)b; // 簡單示例,實際中需要更安全的實現(xiàn) } } // 使用示例 class Program { static void Main() { var intCalc = new ValueCalculator<int>(); Console.WriteLine(intCalc.Add(5, 3)); // 輸出 8 // 下面這行會編譯錯誤,因為 string 是引用類型 // var stringCalc = new ValueCalculator<string>(); } }
where T : class
public class MyClass<T> where T : class { public T Value { get; set; } }
例子
public class Repository<T> where T : class, new() { private List<T> items = new List<T>(); public T CreateItem() { var newItem = new T(); // 可以實例化,因為有 new() 約束 items.Add(newItem); return newItem; } public void DisplayCount() { Console.WriteLine($"Items count: {items.Count}"); } } // 使用示例 class Program { class Customer { public string Name { get; set; } } static void Main() { var repo = new Repository<Customer>(); var customer = repo.CreateItem(); customer.Name = "John Doe"; repo.DisplayCount(); // 輸出 Items count: 1 } }
where T : new()
public class Factory<T> where T : new() { public T CreateInstance() { return new T(); } }
where T : 基類
public class AnimalShelter<T> where T : Animal { public void Shelter(T animal) { animal.Feed(); } }
where T : 接口
public class Sorter<T> where T : IComparable<T> { public void Sort(T[] array) { Array.Sort(array); } }
例子
using System; // 定義一個接口 public interface IDisplayable { void Display(); } // 實現(xiàn)接口的類 public class Product : IDisplayable { public string Name { get; set; } public void Display() { Console.WriteLine($"Product: {Name}"); } } // 使用 where 約束確保 T 實現(xiàn) IDisplayable public class DisplayManager<T> where T : IDisplayable { public void Show(T item) { item.Display(); // 安全調(diào)用,因為知道 T 有 Display 方法 } } // 使用示例 class Program { static void Main() { var product = new Product { Name = "Laptop" }; var manager = new DisplayManager<Product>(); manager.Show(product); } }
where T : U
public class DerivedContainer<T, U> where T : U { // T 必須繼承自 U 或?qū)崿F(xiàn) U(如果 U 是接口) }
例子
public class Animal { public virtual void MakeSound() { Console.WriteLine("Some animal sound"); } } public class Dog : Animal { public override void MakeSound() { Console.WriteLine("Bark!"); } } // 約束 T 必須繼承自 Animal public class AnimalShelter<T> where T : Animal { public void LetAnimalMakeSound(T animal) { animal.MakeSound(); // 可以調(diào)用 Animal 的方法 } } // 使用示例 class Program { static void Main() { var shelter = new AnimalShelter<Dog>(); shelter.LetAnimalMakeSound(new Dog()); // 輸出 "Bark!" } }
多重約束
可以為類型參數(shù)指定多個約束
需要注意的是:當與其他約束一起使用時,new() 約束必須最后指定。
public class MyClass<T> where T : class, IDisposable, new() { }
多個類型參數(shù)的約束
對于多個類型參數(shù),每個都可以有自己的約束:
public class MyClass<TKey, TValue> where TKey : IComparable<TKey> where TValue : class,new() { }
約束的優(yōu)點
1、增強類型安全 - 編譯器可以在編譯時捕獲類型不匹配的錯誤。
2、減少運行時轉(zhuǎn)換 - 避免不必要的類型檢查和轉(zhuǎn)換。
3、啟用更多操作 - 知道類型參數(shù)具有某些特性(如特定方法或構(gòu)造函數(shù))后,可以在泛型代碼中 使用這些特性。
4、不會對性能產(chǎn)生可測量的影響。
總結(jié):合理使用泛型約束可以顯著提高代碼質(zhì)量和安全性,但應(yīng)該避免過度使用導(dǎo)致不必要的復(fù)雜性。在大多數(shù)情況下,優(yōu)點遠大于缺點,特別是在開發(fā)庫代碼或框架時。
到此這篇關(guān)于C# Where 泛型約束的實現(xiàn)的文章就介紹到這了,更多相關(guān)C# Where 泛型約束內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#中Predicate<T>與Func<T, bool>泛型委托的用法實例
這篇文章主要介紹了C#中Predicate<T>與Func<T, bool>泛型委托的用法,指出了其用法中的誤區(qū)及易錯點,有助于更好的理解泛型委托的用法,需要的朋友可以參考下2014-09-09C#筆記之EF Code First 數(shù)據(jù)模型 數(shù)據(jù)遷移
EF 中 Code First 的數(shù)據(jù)遷移網(wǎng)上有很多資料,我這份并沒什么特別。Code First 創(chuàng)建視圖網(wǎng)上也有很多資料,但好像很麻煩,而且親測好像是無效的方法(可能是我太笨,沒搞成功),我摸索出了一種簡單有效的方法,這里分享給大家2021-09-09