Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом документе перечислены известные критические изменения в Roslyn после общего выпуска .NET 7 (пакет SDK для .NET версии 7.0.100) до общего выпуска .NET 8.0.100.
Модификаторы ссылок динамических аргументов должны быть совместимы с модификаторами ссылок соответствующих параметров
Представлено в Visual Studio 2022 версии 17.10
Модификаторы ref динамических аргументов должны быть совместимы с модификаторами ref соответствующих параметров при компиляции. Это может привести к сбою разрешения перегрузки, включающей динамические аргументы во время компиляции, а не во время выполнения.
Ранее допускалось несовпадение во время компиляции, и сбой разрешения перегрузки откладывался до времени выполнения.
Например, следующий код ранее компилировался без ошибки, но завершался сбоем с исключением: "Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: лучшее соответствие перегруженного метода для 'C.f(ref object)' имеет некоторые недопустимые аргументы." Теперь это вызовет ошибку компиляции.
public class C
{
public void f(ref dynamic a)
{
}
public void M(dynamic d)
{
f(d); // error CS1620: Argument 1 must be passed with the 'ref' keyword
}
}
Выражение коллекции для реализации IEnumerable
типа должно иметь элементы, неявно преобразуемые в object
Представлено в Visual Studio 2022 версии 17.10
Преобразование коллекции в struct
или class
, которое поддерживает System.Collections.IEnumerable
и не имеет строго типизированного GetEnumerator()
, требует, чтобы элементы коллекции были неявно преобразуемы в object
.
Ранее считалось, что элементы выражения коллекции, ориентированные на реализацию IEnumerable
, преобразуются в object
, и преобразуются только при привязке к применимому методу Add
.
Это дополнительное требование означает, что преобразования выражений коллекции в IEnumerable
реализации обрабатываются согласованно с другими целевыми типами, в которых элементы в выражении коллекции должны быть неявно преобразованы в тип итерации целевого типа.
Это изменение касается выражений коллекций, нацеленных на реализации IEnumerable
, где элементы полагаются на использование целевых типов для параметров методов, строго типизированных к типу Add
.
В приведенном ниже примере сообщается об ошибке, связанной с тем, что _ => { }
невозможно неявно преобразовать в object
.
class Actions : IEnumerable
{
public void Add(Action<int> action);
// ...
}
Actions a = [_ => { }]; // error CS8917: The delegate type could not be inferred.
Чтобы устранить ошибку, выражение элемента может быть явно типизированным.
a = [(int _) => { }]; // ok
a = [(Action<int>)(_ => { })]; // ok
Тип целевого объекта выражения коллекции должен иметь конструктор и Add
метод
Представлено в Visual Studio 2022 версии 17.10
Преобразование выражения коллекции в реализацию struct
или class
System.Collections.IEnumerable
не имеетCollectionBuilderAttribute
целевого типа, чтобы иметь доступный конструктор, который можно вызывать без аргументов, и если выражение коллекции не пусто, целевой тип должен иметь доступный Add
метод, который можно вызвать с одним аргументом.
Ранее конструктор и Add
методы были необходимы для создания экземпляра коллекции, но не для преобразования.
Это означает, что следующий вызов является неоднозначным, так как оба char[]
и string
были допустимыми целевыми типами для выражения коллекции.
Вызов больше не является неоднозначным, так как string
не имеет конструктора или Add
метода без параметров.
Print(['a', 'b', 'c']); // calls Print(char[])
static void Print(char[] arg) { }
static void Print(string arg) { }
ref
Аргументы можно передать в in
параметры
Представлено в Visual Studio 2022 версии 17.8p2
Функция ref readonly
обеспечивает ослабление разрешения перегрузки, позволяя аргументы ref
передавать в параметры in
, когда LangVersion
установлено значение 12 или более позднее.
Это может привести к изменениям в поведении или изменению кода, нарушающему его работу:
var i = 5;
System.Console.Write(new C().M(ref i)); // prints "E" in C# 11, but "C" in C# 12
System.Console.Write(E.M(new C(), ref i)); // workaround: prints "E" always
class C
{
public string M(in int i) => "C";
}
static class E
{
public static string M(this C c, ref int i) => "E";
}
var i = 5;
System.Console.Write(C.M(null, ref i)); // prints "1" in C# 11, but fails with an ambiguity error in C# 12
System.Console.Write(C.M((I1)null, ref i)); // workaround: prints "1" always
interface I1 { }
interface I2 { }
static class C
{
public static string M(I1 o, ref int x) => "1";
public static string M(I2 o, in int x) => "2";
}
Предпочитайте удаление на основе шаблонов, а не на основе интерфейсов в асинхронном режиме using
Представлено в Visual Studio 2022 версии 17.10p3
Асинхронный using
предпочитает выполнять привязку с использованием шаблона на основе метода DisposeAsync()
, вместо интерфейса на основе IAsyncDisposable.DisposeAsync()
.
Например, будет выбран общедоступный DisposeAsync()
метод, а не реализация частного интерфейса:
await using (var x = new C()) { }
public class C : System.IAsyncDisposable
{
ValueTask IAsyncDisposable.DisposeAsync() => throw null; // no longer picked
public async ValueTask DisposeAsync()
{
Console.WriteLine("PICKED");
await Task.Yield();
}
}
Roslyn breaking changes