День 1440. #ЗаметкиНаПолях
Особенность Использования Необязательных Параметров
Мы все любим необязательные параметры методов. Их так просто и удобно использовать. Но есть один момент, при использовании их в отельной библиотеке классов, о котором стоит помнить.
Рассмотрим пример. Сразу скажу, он немного искусственный, но от этого, если вы вдруг столкнётесь с такой ошибкой, она будет казаться ещё более невероятной.
Допустим, мы сделали библиотеку классов для калькулятора:
namespace ThirdPartyLibrary;
public static class Calculator
{
public static int Add(int a = 0, int b = 0)
{
Console.WriteLine($"{a}+{b}");
return a + b;
}
}
}
Простой метод с необязательными параметрами. И код, который её использует:
using ThirdPartyLibrary;
int add = Calculator.Add();
add = Calculator.Add(2);
add = Calculator.Add(2, 3);
Console.ReadLine();
//Вывод:
0+0
2+0
2+3
Пока всё хорошо.
Теперь сделаем небольшое изменение в классе Calculator: изменим значения параметров по умолчанию с 0 на 10.
Соберём проект библиотеки (только его, а не всё решение) и скопируем получившиеся файлы библиотеки ThirdPartyLibrary.dll и ThirdPartyLibrary.pdb из папки \bin\Debug библиотеки в папку \bin\Debug консольного приложения. То есть мы обновили библиотеку и хотим, чтобы наше приложение работало с новой версией.
Теперь из той же папки \bin\Debug консольного приложения запустим приложение (exe файл). Мы ожидаем, что оно будет использовать новую версию библиотеки, и будут использоваться новые значения по умолчанию (10), так?
Но результаты не изменились!
0+0
2+0
2+3
Теперь попробуем пересобрать весь проект и запустить его. Получаем то, чего ожидали:
10+10
2+10
2+3
Дело в том, что, когда вы вызываете метод с необязательными параметрами и не передаете значения для этих необязательных параметров, будут использоваться значения по умолчанию, определённые методом. Но это не всё. Эти значения по умолчанию будут жёстко записаны в скомпилированный код вызывающей стороны! Т.е. когда значения по умолчанию обновятся в определении метода, это не будет отражено в вызывающем объекте до тех пор, пока клиентский код не будет пересобран вместе с новой версией библиотеки.
Таким образом, если существует вероятность того, что проект подключаемой библиотеки может быть обновлён и собран без перекомпиляции проекта вызывающего метода, это риск.
Источник: https://levelup.gitconnected.com/dangers-of-using-optional-parameters-in-net-c-a953315672fb