You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为C#泛型<TId>定义仅允许long或Guid的编译时约束?

问题解答

直接通过C#内置的泛型约束语法无法实现仅允许long或Guid作为泛型参数的编译时限制,因为C#的泛型约束仅支持以下几类规则:

  • 基类约束(指定必须继承自某类)
  • 接口约束(指定必须实现某接口)
  • 值类型/引用类型约束(struct/class)
  • 无参数构造函数约束(new())

而long和Guid没有共同的非object基类或专属接口,常规约束无法满足需求。不过可以通过两种编译时校验方案实现目标,且不需要依赖子类:

方案1:自定义Roslyn分析器

编写自定义Roslyn分析器,在编译阶段检查泛型参数TId是否为long或Guid,若不符合则直接抛出编译错误。这种方式完全是编译时校验,不会影响运行时性能,也无需额外的代码结构。

方案2:利用隐式运算符的编译时校验 trick

定义一个标记类,仅为long和Guid添加隐式转换到该类的运算符,并将标记类的构造函数设为私有:

public sealed class IdConstraint
{
    private IdConstraint() { }
    
    public static implicit operator IdConstraint(long _) => new();
    public static implicit operator IdConstraint(Guid _) => new();
}

public abstract class Typed<TId>
{
    // 编译时触发校验:仅当TId是long或Guid时,default(TId)才能转换为IdConstraint
    private static readonly IdConstraint _check = default(TId);
}

当TId不是long或Guid时,default(TId)无法完成隐式转换,编译器会直接报错,实现编译时限制。该方案纯靠C#语法实现,无需额外工具,且JIT会优化掉未使用的静态字段,不会产生运行时开销。

内容的提问来源于stack exchange,提问作者Sarwan Surchi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 07:17:36