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

C# 12环境下集合初始化器引发CS0121歧义调用问题求助

C# 12环境下集合初始化器引发CS0121歧义调用问题求助

我最近碰到个特别费解的问题,想请大家帮忙捋捋:我和另外两位开发者组队做项目,过去几个月我独自用C# 12开发了一个模块,最近两位同事拉取代码后,一位编译运行都正常,另一位却直接碰到了CS0121(调用歧义)的编译错误。

先给大家说下核心的代码场景:我定义了一个Foo类,有两个构造函数——一个接收string参数,另一个接收IEnumerable<Bar>(Bar是一个带隐式字符串转换的记录类型)。同时类里还有个public static readonly的None字段,用来包装一个空的Bar集合,代码是这样的:

public static readonly Foo None = new([]);

我和同事A的环境里这段代码完全能正常编译,但同事B那边直接报了CS0121错误,提示内容是:

The call is ambiguous between the following methods or properties:
'Foo.Foo(IEnumerable)' and 'Foo.Foo(string)'.

同事B把代码改成下面这样后,就顺利编译通过了:

public static readonly Foo None = new(Array.Empty<Bar>());

我们三个人都反复确认过,项目的目标框架都是C# 12和**.NET 8.0**。我一开始还怀疑是不是C#13里集合表达式的破坏性变更,但我们明明都锁定了C#12,肯定不是这个原因。后来我还按照类似问题的建议,把自己的SDK降级到8.0.201,代码还是能正常编译,完全复现不出同事B的错误。

下面是我写的模拟问题的测试代码(虽然我自己这边跑不出来错误,但尽量还原了真实场景):

using System.Diagnostics;
using System.Linq;

namespace Foobar;

internal class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Running on SDK " + GetSdkVersion()); // 无论用8.0.201还是9.0.100都能编译
        Foo none = Foo.None;
        Console.WriteLine(none.ToString()); // 输出 "Foo: [ (from Bar constructor)]"

        Bar[] helloWorldBars = ["hello", "world"];
        Foo helloWorldFoo = new(helloWorldBars);
        Console.WriteLine(helloWorldFoo.ToString()); // 输出 "Foo: [(hello),(world) (from Bar constructor)]"

        Foo fromString = new("spam");
        Console.WriteLine(fromString.ToString()); // 输出 "Foo: [spam (from string constructor)]"

        Console.Write("Press ENTER to quit.");
        Console.ReadLine();
    }

    private static string GetSdkVersion()
    {
        Process process = new();
        process.StartInfo.FileName = "dotnet.exe";
        process.StartInfo.Arguments = "--version";
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.Start();

        string version = process.StandardOutput.ReadToEnd()?.TrimEnd() ?? "UNKNOWN";

        process.WaitForExit();
        return version;
    }
}

public class Foo
{
    private readonly string fooData;

    /// <summary>返回包装空Bar集合的Foo实例</summary>
    public static readonly Foo None = new([]); // 同事B编译时触发CS0121错误
    // public static readonly Foo None = new(Array.Empty<Bar>()); // 无歧义的替代写法

    /// <summary>用字符串构造Foo</summary>
    public Foo(string fooData)
    {
        this.fooData = fooData + " (from string constructor)";
    }
    /// <summary>用Bar集合构造Foo</summary>
    public Foo(IEnumerable<Bar> bars)
    {
        this.fooData = string.Join(',', bars.Select(b => $"({b})")) + $" (from {nameof(Bar)} constructor)";
    }
    public override string ToString() => $"{nameof(Foo)}: [{fooData}]";
}

public record Bar(string BarData)
{
    public override string ToString() => BarData;
    public static implicit operator Bar(string barData) => new(barData);
}

还有我的global.json配置:

{
  "sdk": {
    "version": "8.0.201",
    "rollForward": "disable"
  }
}

有没有大佬能帮忙分析下这到底是怎么回事啊?实在想不通为什么相同的目标框架和语言版本下,三个人的编译结果会不一样...

备注:内容来源于stack exchange,提问作者mdirks

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 10:40:28