Рассмотрим следующий код:
#nullable enable
class Foo
{
public string? Name { get; set; }
public bool HasName => Name != null;
public void NameToUpperCase()
{
if (HasName)
{
Name = Name.ToUpper();
}
}
}
На Name = Name.ToUpper () я получаю предупреждение, что Name - это возможная нулевая ссылка, которая явно неверна. Я могу вылечить это предупреждение, вставив HasName, так что условие if (Name! = Null).
Есть ли какой-нибудь способ, которым я могу указать компилятору, что истинный ответ от HasName подразумевает ограничение не обнуляемости для Name?
Это важно, потому что HasName может на самом деле тестировать намного больше вещей, и я могу захотеть использовать его в нескольких местах, или это может быть публичной частью поверхности API. Есть много причин, чтобы захотеть включить нулевую проверку в свой собственный метод, но это, похоже, нарушает проверку ссылок на пустые значения.
c#
nullable-reference-types
Джон Мелвилл
источник
источник
HasValue
на обнуляемый тип, а не проверять егоnull
. Это, вероятно, не влияет на вашу проблему, хотя.#nullable disable
потом#nullable enable
илиrestore
снова ( docs.microsoft.com/en-us/dotnet/csharp/… ).!
оператор "dammit" .if(HasName) { Name = Name!.ToUpper(); }
Ответы:
Я осмотрел различные атрибуты
System.Diagnostics.CodeAnalysis
и не смог найти ничего подходящего, что очень разочаровывает. Самое близкое, что вы можете получить к тому, что вы хотите, это:Я знаю, это выглядит довольно громоздко. Вы можете посмотреть в документах MSDN об атрибутах , которые можно обнулять , возможно, вы найдете что-то более аккуратное
источник
if(Name != null) return Null.ToUpper()
, не будет никакого предупреждения для нулевой разыменования, даже если технически это условие гонки TOCTOU. Я помню, как Мэдс Торгерсен говорил о том, как они это считали, но это сгенерировало бы столько ложных срабатываний, что вся функция ссылочных типов, обнуляемая, была бы практически бесполезна - 99% времени ваши свойства не будут изменены другим потоком. Поэтому все, что вам нужно сделать, - это создать атрибут, который будет проверять это свойство как проверку на нулевое значение в другом свойстве.String является ссылочным типом, а Nullable (например
int?
) является Nullable типами значений. Таким образом, вы не можете сделать этоstring? myString
; Что вам нужно, это:источник