导读:本期聚焦于小伙伴创作的《C# 泛型(Generics)的约束有哪些 - where关键字的高级用法》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C# 泛型(Generics)的约束有哪些 - where关键字的高级用法》有用,将其分享出去将是对创作者最好的鼓励。

C#的泛型允许我们定义类型参数化的类、方法、接口等,而泛型约束通过where关键字限制类型参数的可用类型,既能保证类型安全,又能让类型参数调用特定的成员。

泛型约束的基本类型

C#支持多种类型的泛型约束,不同的约束对应不同的类型限制规则,以下是常用的约束类型:

1. 类约束

类约束要求类型参数必须是某个基类或者从该基类派生的类型,语法为where T : 基类名

// 定义基类
public class BaseEntity
{
    public int Id { get; set; }
}

// 泛型类,约束T必须是BaseEntity或其派生类
public class Repository<T> where T : BaseEntity
{
    public void PrintId(T entity)
    {
        // 因为约束了T是BaseEntity的子类,所以可以直接访问Id属性
        Console.WriteLine(entity.Id);
    }
}

2. 接口约束

接口约束要求类型参数必须实现指定的接口,语法为where T : 接口名,一个类型参数可以实现多个接口约束。

// 定义接口
public interface ILog
{
    void WriteLog(string message);
}

// 泛型方法,约束T必须实现ILog接口
public void ExecuteWithLog<T>(T instance) where T : ILog
{
    instance.WriteLog("开始执行操作");
    // 其他业务逻辑
    instance.WriteLog("操作执行完成");
}

3. 引用类型约束

引用类型约束要求类型参数必须是引用类型,语法为where T : class,适用于需要操作对象引用的场景。

// 泛型方法,约束T必须是引用类型
public void CheckNull<T>(T value) where T : class
{
    if (value == null)
    {
        Console.WriteLine("值为空");
    }
    else
    {
        Console.WriteLine("值不为空");
    }
}

4. 值类型约束

值类型约束要求类型参数必须是值类型,语法为where T : struct,注意值类型约束不能和new()构造函数约束同时使用。

// 泛型方法,约束T必须是值类型
public T Add<T>(T a, T b) where T : struct
{
    // 值类型可以直接使用动态类型相关操作,这里以int为例的逻辑
    return (dynamic)a + b;
}

5. 构造函数约束

构造函数约束要求类型参数必须有无参数的公共构造函数,语法为where T : new(),方便在泛型内部创建类型实例。

// 泛型方法,约束T必须有公共无参构造函数
public T CreateInstance<T>() where T : new()
{
    return new T();
}

// 使用示例
public class User
{
    public string Name { get; set; }
}

// 调用时T为User,User有默认无参构造函数,符合约束
User user = CreateInstance<User>();

6. 裸类型约束

裸类型约束是指一个类型参数作为另一个类型参数的约束,语法为where T : U,要求T必须是U或者U的派生类。

// 泛型方法,约束T必须是U或者U的派生类
public void CopyData<T, U>(T source, U target) where T : U
{
    // 这里T可以安全转换为U类型,调用U的相关成员
}

where关键字的高级用法

多重约束的组合使用

一个类型参数可以同时设置多个约束,多个约束之间用逗号隔开,需要注意约束的排列顺序:类约束或引用类型/值类型约束必须放在第一个,然后是接口约束,最后是new()构造函数约束(如果有)。

// 泛型类,T同时有多个约束:必须是BaseEntity的派生类、实现ILog接口、有公共无参构造函数
public class Service<T> where T : BaseEntity, ILog, new()
{
    public void Process()
    {
        T instance = new T();
        Console.WriteLine(instance.Id);
        instance.WriteLog("处理完成");
    }
}

多个类型参数的约束定义

如果泛型有多个类型参数,每个类型参数都可以单独设置where约束,每个where子句对应一个类型参数。

// 泛型类有两个类型参数,分别设置不同的约束
public class Mapper<TSource, TTarget> 
    where TSource : class 
    where TTarget : class, new()
{
    public TTarget Map(TSource source)
    {
        TTarget target = new TTarget();
        // 映射逻辑
        return target;
    }
}

泛型方法中的约束

where关键字不仅可以用在泛型类、泛型接口上,也可以用在一个单独的方法上,定义方法的泛型参数约束。

public class Utility
{
    // 泛型方法,约束T必须是值类型
    public static bool Compare<T>(T a, T b) where T : struct
    {
        return a.Equals(b);
    }
}

// 调用泛型方法,传入int类型参数,符合值类型约束
bool result = Utility.Compare(1, 2);

泛型约束的使用场景和注意事项

泛型约束的核心作用是缩小类型参数的范围,让代码在编译期就能检查类型合法性,避免运行时出现无效类型转换的错误。比如在仓储模式中,我们通常约束实体类必须继承基类,保证所有实体都有统一的Id属性;在依赖注入场景中,约束服务类必须实现特定接口,保证服务的功能符合预期。

需要注意,泛型约束不能限制静态成员的使用,因为静态成员属于类型本身,和类型参数无关。另外,过多的约束会降低泛型的灵活性,所以定义约束时要平衡类型安全和复用性,只添加必要的约束。

约束类型语法格式作用说明
类约束where T : 基类名类型参数必须是基类或其派生类
接口约束where T : 接口名类型参数必须实现指定接口
引用类型约束where T : class类型参数必须是引用类型
值类型约束where T : struct类型参数必须是值类型
构造函数约束where T : new()类型参数必须有公共无参构造函数
裸类型约束where T : U类型参数T必须是U或其派生类

C#_Genericswhere关键字泛型约束类型参数约束修改时间:2026-06-27 21:34:06

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。