Проверка на null перед ToString ()

Вот сценарий ...

if (entry.Properties["something"].Value != null)
  attribs.something = entry.Properties["something"].Value.ToString();

Хотя это эффективно и работает правильно, мне это кажется уродливым. Если я не проверяю значение NULL перед выполнением ToString (), он генерирует исключение, если свойство было равно NULL. Есть ли лучший способ справиться с этим сценарием?

Очень признателен!


person Dscoduc    schedule 15.02.2009    source источник
comment
Итак, каким должен быть результат, если значение равно нулю?   -  person Zach Scrivena    schedule 15.02.2009
comment
Он будет использовать значение по умолчанию, присвоенное attribs.something.   -  person Dscoduc    schedule 15.02.2009
comment
@dscoduc Я ищу информацию о вашем HTA jQuery за 2009 год. Это все еще есть? Ваш блог и сайт отключены.   -  person yzorg    schedule 08.07.2012
comment
см. также: stackoverflow.com/questions/24318654   -  person dreftymac    schedule 20.06.2014
comment
Мой вопрос был из 2009 года, а тот, на который вы ссылались, из 2010 года ... так что второй является моей копией, не так ли?   -  person Dscoduc    schedule 06.08.2016


Ответы (11)


Обновление 8 лет спустя (вау!), Чтобы охватить условный оператор null в c # 6:

var value = maybeNull?.ToString() ?? String.Empty;

Другие подходы:

object defaultValue = "default";
attribs.something = (entry.Properties["something"].Value ?? defaultValue).ToString()

Я тоже использовал это, что не очень умно, но удобно:

public static string ToSafeString(this object obj)
{
    return (obj ?? string.Empty).ToString();
}
person Rex M    schedule 15.02.2009
comment
Вы не знаете, можно ли заменить значение по умолчанию на string.Empty? - person Dscoduc; 15.02.2009
comment
+1 и ответ: Только что протестировал и отлично работает ... Спасибо! - person Dscoduc; 15.02.2009
comment
Обратите внимание, что если метод, выполняющий вызов, запускается более одного раза и атрибуты используются повторно, вы можете перезаписать действительные данные, полученные при 1 вызове, на значение по умолчанию при следующем вызове. - person xcud; 15.02.2009
comment
@xcud: Верно. В этом случае он должен использовать следующий код: attribs.something = (entry.Properties [something] .Value ?? (objcet) attribs.something) .ToString (); - person configurator; 15.02.2009

Если вы ориентируетесь на .NET Framework 3.5, на мой взгляд, самым элегантным решением будет метод расширения.

public static class ObjectExtensions
{
    public static string NullSafeToString(this object obj)
    {
        return obj != null ? obj.ToString() : String.Empty;
    }
}

Затем использовать:

attribs.something = entry.Properties["something"].Value.NullSafeToString();
person Dale Ragan    schedule 15.02.2009
comment
Красивый. Я как раз столкнулся с преобразованием из 1.1 в 4.0, и в 1.1 фактически вернулось значение null.ToString (), так что теперь у меня есть пара тысяч вхождений, которые нужно проверить на нулевую безопасность. Если я заставлю это работать, это сделает переход намного более плавным! - person Nicolas78; 13.11.2010
comment
Вау, это сэкономило мне много времени! Спасибо! - person Brad; 25.08.2011

Добавление пустой строки к объекту - это распространенная идиома, которая позволяет выполнять нулевое ToString преобразование, например:

attribs.something = ""+entry.Properties["something"].Value;

Когда entry.Properties["something"].Value равно null, тихо возвращается пустой string.

Изменить. Начиная с C # 6, вы можете использовать оператор ?., чтобы избежать null проверки еще более простым способом:

attribs.something = entry.Properties["something"].Value?.ToString();
//                                                     ^^
person Sergey Kalinichenko    schedule 12.09.2013
comment
это более лаконично, чем странный вызов Convert.ToString. - person thepaulpage; 24.11.2015
comment
@thepaulpage В C # 6 есть еще лучший способ. - person Sergey Kalinichenko; 24.11.2015

Вы не можете сделать:

attribs.something = entry.Properties["something"].Value as string;
person NotDan    schedule 26.04.2009
comment
Нет, нельзя; если он 'null', вы получите ошибку нулевой ссылки. - person George Stocker; 07.09.2010
comment
это работает, поскольку оно возвращает пустую строку, если значение равно нулю, и не генерирует исключение. - person live-love; 11.05.2011
comment
Это не работает для типов значений. 'строка str = myFloat как строка;' терпит неудачу. Вы получите следующую ошибку компилятора Невозможно преобразовать тип 'float' в 'string' с помощью преобразования ссылки, преобразования упаковки, преобразования распаковки, преобразования оболочки или преобразования нулевого типа - person CleanCoder; 14.01.2012
comment
Nooooo, если тип не является строкой, всегда будет возвращать null !!! это кастинг, а не конверсия! и не будет работать с типами значений! - person Sawan; 27.11.2012

attribs.something = String.Format("{0}", entry.Properties["something"].Value);

Хотя не уверен в производительности ...

person Community    schedule 04.03.2011

В C # 6.0 это можно сделать очень элегантно:

attribs.something = entry.Properties["something"].Value?.ToString();

А вот статья о новом нулевом условном операторе.

person ZuoLi    schedule 09.02.2016

Как вариант ответа RexM:

attribs.something = (entry.Properties["something"].Value ?? attribs.something).ToString()

Единственным недостатком будет то, что атрибуту attribs.something будет присвоено значение (в этом примере самому себе), даже если entry.Properties ["something"]. Value было равно null, что могло бы быть дорогостоящим, если бы свойство .something выполняло другую обработку и / или эта строка выполняется много (как в цикле).

person PhilChuang    schedule 15.02.2009

Чтобы делать именно то, что вы пытаетесь сделать, всегда можно использовать вспомогательный метод:

CopyIfNotNull(entry.Properties["something"].Value, out attribs.something);

void CopyIfNotNull(string src, out string dest)
{
  if(src != null)
    dest = src;
}
person Mike Hall    schedule 15.02.2009
comment
Разве вам не нужно указывать второй аргумент CopyIfNotNull? - person Dscoduc; 15.02.2009
comment
Ага. Я понял это после того, как выложил. - person Mike Hall; 16.02.2009

Возможно ли как-то сделать что-то вроде ответа Дейла Рагана выше, но переопределить ToString () вместо создания нового метода NullSafeToString ()? Я бы хотел, чтобы это (или возвращение «null») было поведением по умолчанию. Компилятор (Visual C # 2010 Express) не жалуется, когда я добавляю следующий метод в общедоступный статический класс ObjectExtensions, но метод не вызывается ...

public static String ToString(this Object obj)
{
    if (obj == null)
    {
        return "null";
    }
    else
    {
        return obj.GetType().Name;
    }
}
person Dave the Rave    schedule 04.03.2011
comment
Конечно, поскольку методы экземпляра имеют более высокий приоритет, чем методы расширения - person codymanix; 20.06.2011

Как насчет использования вспомогательного метода вроде этого:

attribs.something = getString(
    entry.Properties["something"].Value, 
    attribs.something);

static String getString(
    Object obj,
    String defaultString)
{
    if (obj == null) return defaultString;
    return obj.ToString();
}

В качестве альтернативы вы можете использовать оператор ??:

attribs.something = 
    (entry.Properties["something"].Value ?? attribs.something).ToString();

(обратите внимание на повторный вызов ToString(), когда значение равно null)

person Zach Scrivena    schedule 15.02.2009

person    schedule
comment
40-Love - нет, это возвращает ноль, а не пустую строку, если значение равно нулю. - person Chris Peacock; 05.02.2015
comment
@ChrisPeacock нет, проверьте документацию: возвращаемое значение Convert.ToString (значение объекта) - это строковое представление значения 'value' или String.Empty, если значение равно нулю. Быстрая проверка в реальной программе подтверждает это. - person Rob Gilliam; 11.04.2018