(Использование ASP.NET Core 7 и VS2022)
У меня есть служебная функция, которую я заимствовал из старого проекта .NET:
Оригинал выглядел так:
public static string WriteString(object str)
{
if (str == null)
return "";
else
return str.ToString().Trim();
}
Я преобразовал это в это:
public static string WriteString(object str)
{
object s = str ?? "";
return s.ToString().Trim();
}
Но я все еще получаю предупреждение «Разыменование возможно нулевой ссылки». Я что-то пропустил? Мои переменные не могут быть нулевыми, потому что я использую оператор объединения нулевых значений. Так что же беспокоит VS?
@phuzi, что неудобно, поскольку «Ваше переопределение ToString() не должно возвращать пустую или нулевую строку».
Я задала вопрос, связанный с этим. Меня не совсем убедили причины, по которым ToString()
позволяет возвращать ноль...
В Visual Studio, если вы перейдете к определению класса Object
, вы увидите подпись .ToString()
.
//
// Summary:
// Returns a string that represents the current object.
//
// Returns:
// A string that represents the current object.
public virtual string? ToString();
string?
приводит к тому, что str.ToString()
оценивается как string?
, а .Trim()
может работать только с необнуляемым string
. Технически вы никогда не получите ошибку, но вы можете выполнить дополнительную проверку на нулевое значение для str.ToString() != null
или вы можете сделать str.ToString()!.Trim()
просто чтобы удовлетворить компилятор
Проекты .NET Framework не выдают это предупреждение, поскольку подпись для .ToString()
отличается.
public virtual string ToString() => this.GetType().ToString();
Вы предполагаете, что ToString()
всегда будет возвращать здесь ненулевое строковое значение и играете с NullReferenceExce[tion. Лучше писать код защитно и проверять значение null на каждом этапе.
для меня это «нет». если что-то реализует ToString как нулевое значение или выдает исключение, мне лучше узнать об этом через исключение - чтобы в будущем быть осторожным с такой библиотекой. кстати, настройки Rider по умолчанию не выдают такого рода предупреждений. возможно, есть исключение для ToString, не уверен
Странно, но я получаю предупреждение «Возможное исключение NullReferenceException» в Rider.
Хм, я тестировал проект .NET Framework с нулевыми значениями — предупреждения, но если я вставлю этот код в .net 7 с включенным нулевым значением — я получаю предупреждение, как в Visual Studio.
Ах, сигнатура метода для .NET Framework другая... public virtual string ToString ();
ок, спасибо, исправлю свой ответ
Вы можете сделать следующее:
public static string WriteString(object str)
{
return s?.ToString().Trim() ?? "";
}
Если какой-либо из возможных объектов в вашем проекте может возвращать значение NULL в результате функции ToString, вы также можете добавить проверку для этого, чтобы избежать вызова Trim() для объекта NULL:
public static string WriteString(object str)
{
return s?.ToString()?.Trim() ?? "";
}
Что s
и ToString()
ещё могут вернуться null
!
@phuzi, ты прав, я понял это и адаптировал свой ответ.
Как утверждали другие, Object.ToString()
возвращает string?
, который может возвращать нулевое значение.
Вот документация: Object.ToString
И фактическая реализация:
/// <summary>Returns a string that represents the current object.</summary>
/// <returns>A string that represents the current object.</returns>
public virtual string? ToString()
{
// The default for an object is to return the fully qualified name of the class.
return GetType().ToString();
}
Вероятно, вам следует проверять значение null на каждом шаге, прибегая к ""
, когда любой шаг возвращает нулевое значение.
public static string WriteString(object str) =>
str?.ToString()?.Trim() ?? "";
Интересно, что сигнатура метода .NET Framework `Object.Tostring() отличается
public virtual string ToString ();
Если бы вы ориентировались на .NET Framework, ваш код вообще не выдал бы никаких предупреждений.
Спасибо. Я знал, что в .NET он не выдает предупреждений, потому что я использовал его там без проблем. Но ваше решение отлично работает.
И наконец (возможно) создайте расширение и используйте лучшее имя:
public static string ToStringTrimmedOrEmpty(this object obj)
=> obj?.ToString()?.Trim() ?? string.Empty;
Вместо того, чтобы переписывать весь код, чтобы избавиться от этих предупреждений, вы также можете отключить определенные предупреждения в Visual Studio. См. эту статью Microsoft.
Список всех обнуляемых предупреждений можно найти здесь.
Проблема в том, что Object.ToString() возвращает
string?