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

C# with关键字在泛型结构体约束下编译失败,是Bug还是预期行为?

C#泛型struct中使用with关键字的编译错误:预期行为及原因

这是预期行为,并非Bug,具体原因如下:

  1. with表达式的依赖逻辑
    with表达式的核心是基于**具体类型的可修改成员(init或set属性)**创建对象副本并修改指定属性。编译器必须在编译阶段明确知晓目标成员的可修改性,才能生成正确的副本创建代码。

  2. 泛型约束的局限性
    在泛型方法DoSomethingWithGenericConstrainedToStruct中,T的约束仅为struct, ICountSomething:

  • 接口ICountSomething只定义了Counter的get访问器,没有暴露它的init或set能力;
  • 编译器无法保证所有符合约束的struct类型,都拥有一个可通过对象初始器修改的Counter成员(比如某些实现该接口的struct可能将Counter定义为只读字段,完全不支持修改)。

由于编译阶段无法验证T类型的Counter是否满足with表达式的修改要求,因此会抛出编译错误。

  1. 具体结构体可正常工作的原因
    对于ActualStruct这种具体类型,编译器能直接识别到它的Counter是init属性,明确支持通过对象初始器修改,因此with表达式可以正常编译执行。

泛型场景的替代实现方案

如果需要在泛型逻辑中实现类似的修改效果,可以在接口中定义专属的修改方法,让结构体实现该方法:

public interface ICountSomething<T> where T : struct, ICountSomething<T>
{
    int Counter { get; }
    T WithIncrementedCounter();
}

public struct ActualStruct : ICountSomething<ActualStruct>
{
    public string Name { get; init; }
    public int Counter { get; init; }

    public ActualStruct WithIncrementedCounter()
    {
        return this with { Counter = Counter + 1 };
    }
}

public class Blah<T>
    where T : struct, ICountSomething<T>
{
    public T DoSomethingWithGenericConstrainedToStruct(T input)
    {
        return input.WithIncrementedCounter();
    }
}

内容的提问来源于stack exchange,提问作者Steve Wilford

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 07:01:09