Разбираем Атрибут OverloadResolutionPriority в C# 13
C# 13 добавляет поддержку нового атрибута OverloadResolutionPriority. Этот атрибут является узкоспециализированным, поэтому большинство из вас не будет его использовать. Тем не менее, это приятное дополнение к языку, и о нём стоит знать, если вы пишете библиотеки.
Рассмотрим простой пример:
Sample.Test(); // Вывод: Test 1
static class Sample
{
public static void Test()
=> Console.WriteLine("Test 1");
}
Если вы захотите обновить сигнатуру и добавить новый необязательный параметр:
Sample.Test(); // Вывод: Test 1
static class Sample
{
public static void Test(
[CallerMemberName]string name = "")
=> Console.WriteLine("Test 1");
}
Но это ломает бинарный код, поскольку метода без параметров больше не существует. Лучшим решением было бы добавление перегрузки, но это не сработает:
Sample.Test(); // Вывод: Test 1
static class Sample
{
public static void Test()
=> Console.WriteLine("Test 1");
public static void Test(
[CallerMemberName]string name = "")
=> Console.WriteLine("Test 2");
}
Больше нет ломающего изменения. Но приложение выведет на консоль «Test 1». Причина в том, что компилятор предпочитает перегрузку без параметров, а не перегрузку с параметром по умолчанию, поскольку она лучше соответствует вызову.
Обратите внимание, что удаление первой перегрузки сломает бинарный код. Вы не можете это делать в библиотеке. Новый атрибут OverloadResolutionPriority позволяет указать приоритет разрешения перегрузки для компилятора. Компилятор выберет совместимую перегрузку с наивысшим приоритетом.
Sample.Test(); // Вывод: Test 2
static class Sample
{
[OverloadResolutionPriority(-1)]
public static void Test()
=> Console.WriteLine("Test 1");
public static void Test(
[CallerMemberName]string name = "")
=> Console.WriteLine("Test 2");
}
Используя этот атрибут, вы теперь можете добавить новую перегрузку, не нарушая существующий код. Компилятор выберет перегрузку с наивысшим приоритетом.
Вы также можете использовать этот атрибут для приоритизации некоторых перегрузок, которые требуют неявных преобразований:
Sample.Test(100); // Вывод: byte
Sample.Test(1000); // Вывод: int
static class Sample
{
public static void Test(int a)
=> Console.WriteLine("int");
[OverloadResolutionPriority(1)]
public static void Test(byte a)
=> Console.WriteLine("byte");
}
Источник: https://www.meziantou.net/understanding-overloadresolutionpriority-attribute-in-csharp-13.htm