Я работаю в команде с двумя другими разработчиками. Последние несколько месяцев я самостоятельно работал над проектом на C# 12, и только недавно другие разработчики извлекли мой код и запустили его. Для одного из них это сработало нормально, но другой столкнулся с ошибкой компиляции CS0121 в следующем контексте.
У меня есть класс с двумя конструкторами. Один конструктор принимает строку; другой принимает IEnumerable данных (экземпляры типа записи). Этот класс также имеет общедоступное статическое поле только для чтения None, которое оборачивает пустую коллекцию данных:
public static readonly Foo None = new([]);
Для меня и коллеги А этот код скомпилировался без проблем. Но коллега Б не смог скомпилировать код из-за ошибки CS0121 о том, что вызов был неоднозначным между двумя конструкторами:
"The call is ambiguous between the following methods or properties: 'Foo.Foo(IEnumerable)' and 'Foo.Foo(string)'."
Коллега Б изменил строку на
public static readonly Foo None = new(Array.Empty());
и затем смог скомпилировать код.
Мы убедились, что для всех троих код был настроен на C# 12 и .NET 8.0
Есть предположения, что происходит? На секунду я задумался, связано ли это как-то с критическими изменениями в C# 13, связанными с выражениями коллекций, но мы все работаем на C# 12, поэтому этого не может быть.
Один из комментариев ниже предположил, что это может быть дубликатом этого вопроса. Как было предложено в этом вопросе, я понизил свой SDK до 8.0.201, но все равно смог успешно скомпилировать.
Вот какой-то фиктивный код, который имитирует проблему, с которой мы столкнулись - хотя, поскольку я не могу воспроизвести ошибку на своем компьютере, возможно, я упускаю какой-то нюанс, который и вызывает проблему.
using System.Diagnostics;
namespace Foobar;
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Running on SDK " + GetSdkVersion()); // compiles using either SDK 8.0.201 or 9.0.100
Foo none = Foo.None;
Console.WriteLine(none.ToString()); // prints "Foo: [ (from Bar constructor)]"
Bar[] helloWorldBars = ["hello", "world"];
Foo helloWorldFoo = new(helloWorldBars);
Console.WriteLine(helloWorldFoo.ToString()); // prints "Foo: [(hello),(world) (from Bar constructor)]"
Foo fromString = new("spam");
Console.WriteLine(fromString.ToString()); // prints "Foo: [spam (from string constructor)]"
Console.Write("Press ENTER to quit.");
Console.ReadLine();
}
private static string GetSdkVersion()
{
// https://stackoverflow.com/questions/709 ... dk-version
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() ?? "UNKONWN";
process.WaitForExit();
return version;
}
}
public class Foo
{
private readonly string fooData;
/// Returns a constructed from an empty collection
public static readonly Foo None = new([]); // CS0121: The call is ambiguous for one of my colleagues
// public static readonly Foo None = new(Array.Empty()); // unambiguous alternative
/// Construct a from a string
public Foo(string fooData)
{
this.fooData = fooData + " (from string constructor)";
}
/// Construct a from a collection of s
public Foo(IEnumerable 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"
}
}
Подробнее здесь: https://stackoverflow.com/questions/792 ... nitializer
CS0121 Неоднозначный вызов с инициализатором коллекции [дубликат] ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение