C Sharp 泛型约束
外观
C#泛型约束[编辑 | 编辑源代码]
泛型约束(Generic Constraints)是C#泛型编程中的核心机制,它允许开发者对泛型类型参数施加限制,确保类型参数满足特定条件(如继承关系、接口实现或构造函数要求)。通过约束,编译器能进行更严格的类型检查,同时提供更丰富的编译时智能提示。
基本概念[编辑 | 编辑源代码]
在未使用约束的泛型中,类型参数可以是任何类型,这可能导致以下问题:
- 无法调用类型参数的特定方法或属性
- 无法保证类型参数符合业务逻辑要求
泛型约束通过where
关键字声明,语法为:
class ClassName<T> where T : constraint_type { ... }
约束类型分类[编辑 | 编辑源代码]
C#提供6种主要约束类型:
1. 基类约束[编辑 | 编辑源代码]
要求类型参数必须继承指定基类:
class AnimalShelter<T> where T : Animal {
public void Feed(T animal) {
animal.Eat(); // 可以调用Animal类的方法
}
}
2. 接口约束[编辑 | 编辑源代码]
要求类型参数必须实现指定接口:
interface ILoggable {
void Log(string message);
}
class Logger<T> where T : ILoggable {
public void Record(T item) {
item.Log("Action performed");
}
}
3. 值类型约束(struct)[编辑 | 编辑源代码]
限制类型参数必须是值类型:
struct NumericCalculator<T> where T : struct {
public T Add(T a, T b) {
return (dynamic)a + (dynamic)b; // 动态类型处理
}
}
4. 引用类型约束(class)[编辑 | 编辑源代码]
限制类型参数必须是引用类型:
class ReferenceContainer<T> where T : class {
public T Item { get; set; }
}
5. 无参数构造函数约束(new())[编辑 | 编辑源代码]
要求类型参数必须有公共无参构造函数:
class Factory<T> where T : new() {
public T CreateInstance() {
return new T();
}
}
6. 组合约束[编辑 | 编辑源代码]
可以组合多个约束条件:
class AdvancedProcessor<T> where T : Animal, ILoggable, new() {
public void Process() {
T obj = new T();
obj.Log("Created");
obj.Eat();
}
}
约束优先级与规则[编辑 | 编辑源代码]
约束声明需遵循特定顺序规则: 1. 主约束(class/struct)必须最先出现 2. 接口约束次之 3. 构造函数约束(new())必须最后
有效示例:
class ValidExample<T> where T : Animal, ILoggable, new() { ... }
无效示例:
// 编译错误:错误的约束顺序
class InvalidExample<T> where T : new(), Animal { ... }
实际应用案例[编辑 | 编辑源代码]
案例1:泛型比较器[编辑 | 编辑源代码]
public class Comparer<T> where T : IComparable<T> {
public bool IsGreater(T a, T b) {
return a.CompareTo(b) > 0;
}
}
// 使用示例
var intComparer = new Comparer<int>();
Console.WriteLine(intComparer.IsGreater(5, 3)); // 输出: True
案例2:数据访问层抽象[编辑 | 编辑源代码]
public interface IRepository<T> where T : class, IEntity {
T GetById(int id);
void Add(T entity);
}
public class Product : IEntity {
public int Id { get; set; }
// 其他属性...
}
public class ProductRepository : IRepository<Product> {
// 实现方法...
}
高级主题[编辑 | 编辑源代码]
协变与逆变约束[编辑 | 编辑源代码]
C# 4.0引入的in
和out
修饰符:
interface IContainer<out T> where T : Animal {
T GetItem();
}
interface IProcessor<in T> where T : Animal {
void Process(T item);
}
默认约束[编辑 | 编辑源代码]
C# 7.3引入unmanaged
约束:
unsafe struct Buffer<T> where T : unmanaged {
public byte* GetBytes(T item) {
return (byte*)&item;
}
}
约束关系图[编辑 | 编辑源代码]
数学表示[编辑 | 编辑源代码]
约束可以形式化表示为: 其中表示各个约束条件。
最佳实践[编辑 | 编辑源代码]
- 优先使用最严格的必要约束
- 避免过度约束导致泛型失去灵活性
- 考虑使用基类/接口约束替代具体类型约束
- 对性能敏感场景,值类型约束可能更高效
常见错误[编辑 | 编辑源代码]
1. 违反约束顺序:
// 错误示例
class ErrorExample<T> where T : new(), IDisposable { }
2. 冲突约束:
// 错误示例:struct和class不能同时使用
class ConflictExample<T> where T : struct, class { }
3. 无法满足的约束:
// 错误示例:string是sealed类,不能作为基类约束
class UnsatifiableExample<T> where T : string { }