Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Dokument werden bekannte änderungen in Roslyn nach .NET 7 general release (.NET SDK Version 7.0.100) bis .NET 8 general release (.NET SDK Version 8.0.100) aufgeführt.
Ref-Modifizierer von dynamischen Argumenten sollten mit den Ref-Modifizierern der entsprechenden Parameter kompatibel sein.
Eingeführt in Visual Studio 2022, Version 17.10
Ref-Modifizierer dynamischer Argumente sollten zur Kompilierungszeit mit den Ref-Modifizierern der entsprechenden Parameter kompatibel sein. Dies kann dazu führen, dass eine Überladungsauflösung mit dynamischen Argumenten während der Kompilierungszeit anstelle der Laufzeit fehlschlägt.
Zuvor bot eine Fehlanpassung bei der Kompilierung die Möglichkeit, die Überladungsauflösung bis zur Laufzeit zu verzögern.
Der folgende Code ließ sich beispielsweise ohne Fehler kompilieren, schlug jedoch mit einer Ausnahme fehl: "Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: The best overloaded method match for ‚C.f(ref object)‘ has some invalid arguments" Jetzt wird ein Kompilierungsfehler ausgegeben.
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
}
}
Sammlungsausdruck für einen Typ, der IEnumerable implementiert, muss Elemente enthalten, die implizit konvertierbar zu object sind.
Eingeführt in Visual Studio 2022, Version 17.10
Die Konvertierung eines Auflistungsausdrucks in einen struct oder class, die System.Collections.IEnumerable implementieren, und nicht über ein stark typisiertes GetEnumerator() verfügen, erfordert, dass die Elemente im Auflistungsausdruck implizit konvertierbar zu object sind.
Zuvor wurde angenommen, dass die Elemente eines Sammlungsausdrucks, der auf eine IEnumerable Implementierung abzielt, in object konvertierbar sind und erst bei der Bindung an die entsprechende Add Methode konvertiert werden.
Diese zusätzliche Anforderung bedeutet, dass Sammlungsausdruckkonvertierungen in IEnumerable Implementierungen konsistent mit anderen Zieltypen behandelt werden, bei denen die Elemente im Sammlungsausdruck implizit in den Iterationstyp des Zieltyps konvertiert werden müssen.
Diese Änderung betrifft Collection-Ausdrücke, die auf IEnumerable-Implementierungen abzielen, bei denen die Elemente auf einen stark typisierten Add-Methodenparametertyp abzielen.
In dem folgenden Beispiel wird ein Fehler gemeldet, dass _ => { } nicht implizit in object konvertiert werden kann.
class Actions : IEnumerable
{
public void Add(Action<int> action);
// ...
}
Actions a = [_ => { }]; // error CS8917: The delegate type could not be inferred.
Um den Fehler zu beheben, kann der Elementausdruck explizit eingegeben werden.
a = [(int _) => { }]; // ok
a = [(Action<int>)(_ => { })]; // ok
Der Zieltyp eines Ausdrucks für eine Collection muss einen Konstruktor und eine Add Methode haben.
Eingeführt in Visual Studio 2022, Version 17.10
Die Konvertierung eines Auflistungsausdrucks in einen struct oder class, die System.Collections.IEnumerable implementiert und nicht über einen CollectionBuilderAttribute verfügen, erfordert, dass der Zieltyp einen zugänglichen Konstruktor hat, der ohne Argumente aufgerufen werden kann. Falls der Auflistungsausdruck nicht leer ist, muss der Zieltyp über eine zugängliche Add Methode verfügen, die mit einem einzigen Argument aufgerufen werden kann.
Zuvor waren der Konstruktor und die Add-Methode für die Konstruktion der Collection-Instanz erforderlich, nicht aber für die Konversion.
Dies bedeutete, dass der folgende Aufruf mehrdeutig war, da beide char[] und string gültige Zieltypen für den Auflistungsausdruck waren.
Der Aufruf ist nicht mehr mehrdeutig, weil string keinen parameterlosen Konstruktor und Add keine Methode hat.
Print(['a', 'b', 'c']); // calls Print(char[])
static void Print(char[] arg) { }
static void Print(string arg) { }
ref Argumente können an in Parameter übergeben werden.
Eingeführt in Visual Studio 2022, Version 17.8p2
Die Funktion ref readonlyParameter hat die Überladungsauflösung gelockert und bietet die Möglichkeit, refArgumente an inParameter zu übergeben, wenn LangVersion auf 12 oder höher festgelegt ist.
Dies kann zu fehlerhaften Änderungen im Verhalten oder im Quellcode führen:
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";
}
Bevorzugung der strukturierten gegenüber der schnittstellenbasierten Entsorgung in async using
Eingeführt in Visual Studio 2022, Version 17.10p3
Ein asynchroner using bevorzugt die Bindung mit einer musterbasierten DisposeAsync() Methode gegenüber der schnittstellenbasierten IAsyncDisposable.DisposeAsync().
Beispielsweise wird die öffentliche DisposeAsync() Methode anstelle der Implementierung der privaten Schnittstelle ausgewählt:
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