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

如何在C#泛型类型中要求类型参数支持with表达式?

在C#中能否为泛型类的类型参数添加支持with表达式的约束?

不可以,目前所有C#版本都没有直接的语法支持让泛型类的类型参数强制支持with表达式。

原因说明

C#对with表达式的操作数有严格的类型限制:

  • C# 9.0中,with的左操作数必须是record类型;
  • C# 10及以后,左操作数可以是record、结构体或匿名类型。

但泛型类型参数的约束体系里,并没有对应的约束项(比如类似where T : record或where T : with-able这样的语法)来限定类型参数必须满足with表达式的使用条件。所以像你示例代码中Updater<TData>类里的input with { Now = DateTime.UtcNow }会触发编译错误CS8858:“接收方类型'TData'不是有效的record类型,也不是结构体类型。”

替代实现方案

虽然无法直接用泛型约束强制支持with,但可以通过以下方式实现类似的复制更新逻辑:

  • 自定义克隆接口:定义包含复制更新方法的接口,让目标类型实现它,再在泛型约束中指定该接口:
public interface IUpdatable<T> where T : IHasTime
{
    T WithUpdatedTime(DateTime newTime);
}

public record MyData : IHasTime, IUpdatable<MyData>
{
    public DateTime Now { get; set; }
    public required string Name { get; set; }
    public bool IsAwesome { get; set; }

    public MyData WithUpdatedTime(DateTime newTime)
    {
        return this with { Now = newTime };
    }
}

public class Updater<TData> where TData : IHasTime, IUpdatable<TData>
{
    public TData MakeUpdatedCopy(TData input)
    {
        return input.WithUpdatedTime(DateTime.UtcNow);
    }
}
  • 使用ICloneable接口:该接口返回类型为object需强制转换,但实现简单:
public class Updater<TData> where TData : IHasTime, ICloneable
{
    public TData MakeUpdatedCopy(TData input)
    {
        var copy = (TData)input.Clone();
        copy.Now = DateTime.UtcNow;
        return copy;
    }
}
  • 反射/表达式树:动态构造对象复制逻辑模拟with行为,但会带来一定性能开销,适合低性能要求场景。

内容的提问来源于Stack Exchange,提问作者Chris Culter

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 18:38:01