Пока я изучал делегат, который на самом деле является абстрактным классом Delegate.cs
, я увидел следующий метод, в котором я не понимаю
- Почему возвращаемое значение использует,
?
хотя это уже ссылочный ( класс ) тип ?[]?
смысл по параметру
Могли бы вы объяснить?
public static Delegate? Combine(params Delegate?[]? delegates)
{
if (delegates == null || delegates.Length == 0)
return null;
Delegate? d = delegates[0];
for (int i = 1; i < delegates.Length; i++)
d = Combine(d, delegates[i]);
return d;
}
c#
.net
null-coalescing-operator
nullable-reference-types
null-coalescing
snr - Восстановить Монику
источник
источник
Ответы:
Пошаговое объяснение:
params Delegate?[] delegates
- это массив обнуляемыйDelegate
params Delegate?[]? delegates
- весь массив может быть обнуляемымПоскольку каждый параметр имеет тип,
Delegate?
а вы возвращаете индексDelegate?[]?
массива, то имеет смысл, что возвращаемый тип - этоDelegate?
иначе, компилятор вернет ошибку, как если бы вы выполняли ретрансляцию, иint
из метода, который возвращает строку.Например, вы можете изменить свой код, чтобы он возвращал такой
Delegate
тип:источник
?
хотя это уже ссылочный (класс) тип?
точно по той же причине, по которой значение аргумента использует?
. Если вы понимаете последнее, вы автоматически понимаете первое. Поскольку метод может возвращать ноль , как параметр может принимать ноль . То есть они оба могут содержать ноль .Since each parameter is of the type Delegate? and you return an index of the Delegate?[]? array, then it makes sense that the return type is Delegate?
Foo?
имеет аккуратноеHasValue
свойство, в то время как егоFoo
необходимо== null
проверить (4) Он сообщает разработчикам, которые читают сигнатуру метода, о том, что нулевые значения - это возможный, ожидаемый и правильный результат. (5) Код выглядит написанным кем-то, кто очень любит обнуляемость и откровенен в этомОбнуляемые ссылочные типы являются новыми в C # 8.0, они не существуют раньше.
Это вопрос документации и того, как создаются предупреждения во время компиляции.
Исключение «объект не установлен как экземпляр объекта» является довольно распространенным явлением. Но это исключение времени выполнения, его можно частично обнаружить уже во время компиляции.
Для регулирования
Delegate d
вы всегда можете позвонитьэто означает, что вы можете кодировать его, во время компиляции ничего не произойдет. Это может вызвать исключения во время выполнения.
Пока для нового
Delegate? p
этот кодексвыдаст предупреждение компилятора.
CS8602: Dereference of a possibly null reference
если вы не напишите:что значит, звоните только если не ноль.
Таким образом, вы документируете переменную может содержать ноль или нет. Он вызывает предупреждения раньше и может избежать нескольких тестов на ноль. То же самое, что у вас есть для int и int? Вы точно знаете, что одно не равно нулю - и вы знаете, как преобразовать одно в другое.
источник
Delegate
которое не является нулевым. Вы просто притворяетесь, что знаете наверняка (что в большинстве случаев достаточно).int
оно никогда не может быть нулевым. Если у вас есть,Delegate
он может быть нулевым (по разным причинам, например, рефлексия). Обычно можно предположить, чтоDelegate
(в C # 8 с включенным NRT) не ноль, но вы никогда не знаете наверняка (откудаint
мы точно знаем).В C # 8 следует явно помечать ссылочные типы как обнуляемые.
По умолчанию эти типы не могут содержать ноль, что-то вроде типов значений. Хотя это не меняет того, как все работает под капотом, проверка типов потребует, чтобы вы делали это вручную.
Данный код подвергается рефакторингу для работы с C # 8, но он не получает преимущества от этой новой функции.
Вот пример обновленного кода (не работает, просто идея), использующего эту функцию. Это спасло нас от нулевой проверки и немного упростило этот метод.
источник
those types are not able to contain null
Обратите внимание, что он генерирует предупреждение компилятора , а не ошибку. Код будет работать нормально (хотя он может генерировать исключения NullReferenceExceptions). Это сделано с учетом обратной совместимости.