Перевірка нульового значення перед ToString ()


76

Ось сценарій ...

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

Хоча це ефективно і працює коректно, це здається мені потворним. Якщо я не перевіряю наявність нуля перед виконанням ToString (), це видає виняток, якщо властивість була нульовою. Чи є кращий спосіб впоратися з цим сценарієм?

Цінується!


Отже, яким повинен бути результат, якщо значення дорівнює нулю?
Zach Scrivena

Він використовував би значення за замовчуванням, призначене attribs.something
Dscoduc

@dscoduc Я шукаю вашу інформацію про HTA jQuery за 2009 рік. Це все ще є? Здається, ваш блог і сайт не в мережі.
yzorg


2
Моє запитання було з 2009 року, а те, на яке ви посилалися, - з 2010 року ... отже, друге - це мій дублікат, ні?
Dscoduc

Відповіді:


128

Оновіть через 8 років (вау!), Щоб охопити нульовий умовний оператор 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();
}

1
Чи знаєте ви з боку, чи "за замовчуванням" можна замінити на string.Empty?
Dscoduc

+1 та відповідь: Просто перевірив і працював чудово ... Дякую!
Dscoduc

Зверніть увагу, що якщо метод, що здійснює виклик, запускається більше одного разу, а атрибути використовуються повторно, можливо, ви перезаписуєте дійсні дані, отримані за 1 виклик, із значенням за замовчуванням для наступного виклику.
xcud

@xcud: Правда. У такому випадку він повинен використовувати такий код: attribs.something = (entry.Properties ["щось"]. Значення ?? (objcet) attribs.something) .ToString ();
конфігуратор

42

Якщо ви націлені на .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();

Гарний. Я просто переживаю перетворення з 1.1 на 4.0, і в 1.1, null.ToString () фактично повернув "", тому я отримав пару тисяч випадків, щоб перевірити наявність нульової безпеки зараз. Якщо я змушу це працювати, це зробить перехід набагато плавнішим!
Nicolas78,

Ого, це коли-небудь заощадило мені багато часу! Дякую!
Бред

39
Convert.ToString(entry.Properties["something"].Value);

40-Love - ні, це повертає null, а не порожній рядок, якщо значення є null.
Кріс Павич

@ChrisPeacock ні, перевірте документацію: повернене значення Convert.ToString (значення об'єкта) - це "Рядове представлення значення" value "або String.Empty, якщо значення є нульовим". Швидка перевірка фактичної програми це підтверджує.
Роб Гілліам,

3

Додавання порожнього рядка до об’єкта є загальною ідіомою, яка дозволяє виконувати нульово безпечне ToStringперетворення, наприклад:

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

Коли entry.Properties["something"].Valueє null, це тихо повертає порожнє string.

Редагувати: Починаючи з C # 6, ви можете використовувати ?.оператор, щоб уникнути nullперевірки ще простішим способом:

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

це більш стисло, ніж дивний виклик Convert.ToString.
thepaulpage

@thepaulpage У C # 6 є ще кращий спосіб
Сергій Калініченко

2

Чи не можете ви зробити:

attribs.something = entry.Properties["something"].Value as string;

Ні, ти не можеш; якщо це значення "нуль", ви отримаєте нульову помилку посилання.
George Stocker

1
це працює, оскільки повертає нульовий рядок, якщо значення є нульовим, і не створює виключення.
live-love

2
Це не працює для типів значень. 'рядок str = myFloat як рядок;' не вдається. Ви отримаєте таку помилку компілятора Неможливо перетворити тип 'float' у 'рядок' за допомогою еталонного перетворення, перетворення боксу, перетворення розпакування, перетворення обтікання або перетворення нульового типу
CleanCoder

1
Неееееееееееееееее, якщо тип не є рядком, завжди повертатиме null !!! це кастинг, а не конверсія! і не буде працювати у типах значень форми!
Саван

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

Не впевнений у продуктивності, хоча ...



1

Як варіація відповіді RexM:

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

Єдиним недоліком було б те, що attribs.something буде присвоєно значення (саме в цьому прикладі), навіть якщо запис. та / або цей рядок виконує багато (як у циклі).


1

Для того, щоб зробити саме те, що ви намагаєтесь зробити, можна завжди використовувати допоміжний метод:

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

void CopyIfNotNull(string src, out string dest)
{
  if(src != null)
    dest = src;
}

Вам не потрібно вказувати "out" у другому аргументі CopyIfNotNull?
Dscoduc

Так. Я зрозумів, що після того, як опублікував.
Майк Холл

1

Чи можна якось зробити щось на зразок відповіді Дейла Рейгана вище , але замінивши 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;
    }
}

2
Звичайно, оскільки методи екземпляру мають вищий пріоритет, ніж методи розширення
codymanix

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

0

Як щодо використання такого допоміжного методу:

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)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.