泛型允许你编写由类型参数化的类和方法,提供类型安全和可重用性,无需代码重复或强制转换。约束限制泛型参数可以是什么类型,使其成员能够安全使用。泛型在 C# 中无处不在(整个集合库都使用泛型)。
泛型解决的问题
=> arr[i];
=> arr[i];
x = Get([] { , , }, );
泛型将类型错误从运行时(强制转换 object)移至编译时,并消除强制转换——安全、可重用的代码。
public class Box<T> // a generic class
{
private T _value;
public void Set(T value) => _value = value;
public T Get() => _value;
}
var box = new Box<string>(); // T = string, type-safe
// generic method
public T Max<T>(T a, T b) where T : IComparable<T> // constraint (see below)
=> a.CompareTo(b) > 0 ? a : b;
where T : class // T must be a reference type
where T : struct // T must be a value type
where T : new() // T must have a parameterless constructor
where T : IComparable<T> // T must implement an interface (so you can call its members)
where T : BaseClass // T must derive from BaseClass
// example: constraint lets you call CompareTo safely
public T Max<T>(T a, T b) where T : IComparable<T>
=> a.CompareTo(b) > 0 ? a : b; // CompareTo is available because of the constraint
约束(where T : ...)限制 T 可以是什么,这样你就可以安全地使用该类型的成员(例如,约束为 IComparable<T> 可以调用 CompareTo)。没有约束,T 可以是任何东西,所以你无法假定任何成员。
List<T>, Dictionary<K,V>, IEnumerable<T>, Task<T>, Nullable<T> ...
→ the entire collections library and much of .NET is generic.
泛型是 C# 的基础——它们被广泛使用(整个集合库、Task<T>、IEnumerable<T> 和无数 API 都是泛型),所以理解它们对任何 C# 开发都至关重要。
泛型解决了一个真实的问题:编写可重用的代码,适用于多种类型,同时保持类型安全——替代方案(使用 object 和强制转换)牺牲了编译时安全性并需要容易出错的强制转换,而为每种类型重复代码是不可维护的。
泛型为你提供可重用、类型安全的代码,无需强制转换和编译时错误检查。约束(where T : ...)是重要的补充:它们限制类型参数可以是什么,既能安全地使用该类型的成员(约束到接口可以调用其方法),又确保正确使用。
理解泛型类和方法、类型推断如何工作以及约束(class、struct、new()、接口/基类约束)对于有效使用泛型密集的 .NET 库和编写自己的可重用、类型安全的抽象都是必要的。
由于泛型支撑着 C# 的集合和框架的大部分,并且泛型是可重用类型安全代码的关键,掌握泛型和约束是有效 C# 开发的核心、经常应用的知识,也是反映类型安全、可重用设计理解的常见主题。
一个包含详细解答的 IT 面试题库——从初级到高级。
捐赠