Freigeben über


Überladungsauflösung mit Span-Parametern in C# 14

Das in .NET 10 enthaltene C# 14 führt neue integrierte Span-Konvertierungen und Regeln zur Typableitung ein. Diese Änderungen machen Überladungen mit Span-Parametern in mehr Szenarien anwendbar.

Vorheriges Verhalten

In C# 13 und früheren Versionen war eine Erweiterungsmethode, die einen ReadOnlySpan<T> oder Span<T> Empfänger verwendet, nicht auf einen Wert vom Typ T[]anwendbar. Daher wurden normalerweise nur Erweiterungsmethoden ohne Span, wie die aus der System.Linq.Enumerable-Klasse, innerhalb von Ausdrucks-Lambdas gebunden.

Neues Verhalten

In C# 14 und später können Methoden mit ReadOnlySpan<T>- oder Span<T>-Parametern an der Typinferenz teilnehmen oder unter mehr Szenarien als Erweiterungsmethoden verwendet werden. Dies macht spanbasierte Methoden wie die aus der System.MemoryExtensions Klasse in mehr Szenarien anwendbar, einschließlich innerhalb von Ausdrucks-Lambdas, bei denen sie Laufzeitausnahmen verursachen, wenn sie mit Interpretation kompiliert werden.

Eingeführt in Version

.NET 10

Typ des Breaking Changes

Diese Änderung ist eine Verhaltensänderung.

Grund für Änderung

Das C#-Sprachfeature ermöglicht vereinfachtes API-Design und die Verwendung (z. B. eine ReadOnlySpan<T> Erweiterungsmethode kann sowohl auf Spannen als auch auf Arrays angewendet werden).

Wenn Sie weiterhin die Ausdrucksinterpretation verwenden müssen, sollten Sie sicherstellen, dass die Nicht-Span-Überladungen gebunden sind, indem Sie beispielsweise Argumente in die genauen Typen umwandeln, die in der Methodensignatur gefordert sind, oder indem Sie die Erweiterungsmethoden als explizite statische Aufrufe verwenden.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

M((array, num) => array.Contains(num)); // fails, binds to MemoryExtensions.Contains
M((array, num) => ((IEnumerable<int>)array).Contains(num)); // ok, binds to Enumerable.Contains
M((array, num) => array.AsEnumerable().Contains(num)); // ok, binds to Enumerable.Contains
M((array, num) => Enumerable.Contains(array, num)); // ok, binds to Enumerable.Contains

void M(Expression<Func<int[], int, bool>> e) => e.Compile(preferInterpretation: true);

Betroffene APIs