Neu in .NET 9.0 [7]: Prioritäten für Methodenüberladungen in C# 13.0
Eine neue Annotation ermöglicht es, über Prioritäten explizit festzulegen, welche Methodenüberladung der Compiler aufrufen soll.
(Bild: Piyawat Nandeenopparit / Shutterstock.com)
- Dr. Holger Schwichtenberg
Mit [OverloadResolutionPriority] im Namensraum System.Runtime.CompilerServices können Entwicklerinnen und Entwickler festlegen, dass bestimmte Überladungen bei der Entscheidung, welche Überladung verwendet werden soll, eine höhere Priorität erhalten. Das hilft zum Beispiel, wenn mit [Obsolet] annotierte Überladungen einer Methode existieren, um zur präferierten Implementierung zu lotsen.
Videos by heise
Bei der neuen Annotation [OverloadResolutionPriority] gibt man eine Integer-Zahl an:
- Je höher die in der Annotation angegebene Zahl ist, umso höher ist die Priorität.
- Die Standardpriorität ist 0.
- Eine Angabe einer negativen Zahl ist möglich, um die Priorität unter den Standard zu senken.
Das folgende Listing zeigt ein Beispiel: Der Aufruf von Print() mit einer Zeichenkette würde ohne [OverloadResolutionPriority] immer zur Implementierung von Print() mit einem String-Parameter gehen, auch wenn diese Überladung als [Obsolete] gekennzeichnet ist. Durch das Einfügen von [OverloadResolutionPriority] lenkt man den Compiler auf eine andere Implementierung um. Würde man in dem Beispiel sowohl der Implementierung mit Parametertyp object als auch ReadOnlySpan<char> den gleichen Prioritätswert geben, wüsste der Compiler nicht, welche Konvertierung er machen soll und verweigert die Übersetzung:
The call is ambiguous between the following methods or properties: 'CS13_OverloadResolutionPriority.Print(object, ConsoleColor)' and 'CS13_OverloadResolutionPriority.Print(ReadOnlySpan<char>, ConsoleColor)'
Mit einem abweichenden Prioritätswert kann man den Compiler zu der einen oder der anderen Implementierung lenken, hier im Listing mit Wert 10 zu public void Print(ReadOnlySpan<char> text, ConsoleColor color).
Die Implementierung public void Print(object text, ConsoleColor color) kommt aber weiterhin zum Einsatz für alle anderen Datentypen, zum Beispiel Zahlen wie 42, denn diese kann der Compiler nicht automatisch in ReadOnlySpan<char> konvertieren.
Folgender Code zeigt den Einsatz der neuen Annotation [OverloadResolutionPriority]:
using System.Runtime.CompilerServices;
namespace NET9_Console.CS13;
public class CS13_OverloadResolutionPriority
{
public void Run()
{
CUI.Demo(nameof(CS13_OverloadResolutionPriority));
// verwendet Print(ReadOnlySpan<char> text)
ReadOnlySpan<char> span = "www.IT-Visions.de".AsSpan();
Print(span);
// verwendet Print(ReadOnlySpan<char> text) wegen OverloadResolutionPriority(10)
Print("Dr. Holger Schwichtenberg");
// verwendet public void Print(object obj)
Print(42);
}
[Obsolete]
//[OverloadResolutionPriority(10)]
public void Print(string text)
{
// Set the console color
Console.ForegroundColor = ConsoleColor.Red;
// Print the text
Console.WriteLine("string: " + text);
// Reset the console color
Console.ResetColor();
}
[OverloadResolutionPriority(1)]
public void Print(object obj)
{
// Set the console color
Console.ForegroundColor = ConsoleColor.Yellow;
// Print the text
Console.WriteLine("Object: " + obj.ToString());
// Reset the console color
Console.ResetColor();
}
[OverloadResolutionPriority(10)]
public void Print(ReadOnlySpan<char> text)
{
// Set the console color
Console.ForegroundColor = ConsoleColor.Green;
// Print the text
Console.WriteLine("ReadOnlySpan<char>: " + text.ToString());
// Reset the console color
Console.ResetColor();
}
}
(Bild: Screenshot (Holger Schwichtenberg))
Wenn man bei public void Print(string text, ConsoleColor color) auch eine Overload Resolution Priority von mindestens 10 setzt
[Obsolete]
[OverloadResolutionPriority(10)]
public void Print(string text, ConsoleColor color)
{
// Set the console color
Console.ForegroundColor = color;
// Print the text
Console.WriteLine("string: " + text);
// Reset the console color
Console.ResetColor();
}
dann wird bei
Print("Dr. Holger Schwichtenberg", ConsoleColor.Yellow);
die Überladung mit string-Parameter genommen, auch wenn diese mit [Obsolete] markiert ist.
(rme)