Я большой поклонник ссылок C#, допускающих значение NULL, и мы включаем их во всех наших новых проектах. Недавно я просматривал PR от коллеги и обнаружил, что атрибут [Необязательный] используется рядом со ссылочным параметром без указания значения по умолчанию. Это будет означать, что мы нарушаем ограничение ссылки, допускающей значение NULL, поскольку значение по умолчанию для аргумента функции будет нулевым, даже если аргумент не помечен как допускающий значение NULL. См. приведенный ниже пример кода:
class Program
{
internal class Data
{
internal int Count { get; set; } = 3;
}
static void Main(string[] args)
{
BadUse();
GoodUse();
}
static void BadUse([Optional] Data data) => Console.WriteLine($"Data: ${data.Count}");
static void BadUse2([Optional, DefaultParameterValue(null)] Data data) => Console.WriteLine($"Data: ${data.Count}");
static void GoodUse(Data? data = null) => Console.WriteLine($"Data: ${data?.Count}");
}
Как вы можете видеть, метод BadUse
выше неверен и вызовет исключение нулевой ссылки без каких-либо предупреждений или ошибок компиляции. Естественно, мы используем более удобочитаемый шаблон необязательных аргументов, как в GoodUse
. Интересно, это ошибка в компиляторе С# или я что-то здесь упускаю? Я бы ожидал увидеть ошибку компиляции или хотя бы какое-то предупреждение. Обратите внимание, что когда атрибут DefaultParameterValue используется в BadUse2
, мы получаем ожидаемое разыменование CS8602 возможно нулевой ссылки.