如何在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
相关产品推荐
相关产品推荐

