Как сделать ToString для возможно нулевого объекта? - PullRequest
78 голосов
/ 21 октября 2010

Есть ли простой способ сделать следующее:

String s = myObj == null ? "" : myObj.ToString();

Я знаю, что могу сделать следующее, но я действительно считаю это взломом:

String s = "" + myObj;

Было бы замечательно, если бы Convert.ToString () имел надлежащую перегрузку для этого.

Ответы [ 12 ]

145 голосов
/ 21 октября 2010

C # 6.0 Редактировать:

С C # 6.0 теперь мы можем получить краткую, безликовую версию оригинального метода:

string s = myObj?.ToString() ?? "";

Или даже используяинтерполяция:

string s = $"{myObj}";

Оригинальный ответ:

String s = (myObj ?? String.Empty).ToString();

или

String s = (myObjc ?? "").ToString()

, чтобы быть еще более кратким.

К сожалению, как уже указывалось, для выполнения этой работы с типами, не относящимися к типу String или Object, вам часто понадобится приведение с любой стороны:

String s = (myObjc ?? (Object)"").ToString()
String s = ((Object)myObjc ?? "").ToString()

Поэтому, хотя это может показаться элегантным, приведение почтивсегда необходимо и не так кратко на практике.

Как и в других местах, я рекомендую, возможно, использовать метод расширения, чтобы сделать это чище:

public static string ToStringNullSafe(this object value)
{
    return (value ?? string.Empty).ToString();
}
39 голосов
/ 21 октября 2010
string.Format("{0}", myObj);

string.Format отформатирует null как пустую строку и вызовет ToString () для ненулевых объектов. Насколько я понимаю, это то, что вы искали.

13 голосов
/ 20 января 2014

Было бы замечательно, если бы Convert.ToString () имел надлежащую перегрузку для этого.

Начиная с .Net 2.0 (примерно за 5 лет до того, как этот вопрос был задан вопрос) было Convert.ToString(Object value), которое, кажется, делает именно то, что вы хотите:

http://msdn.microsoft.com/en-us/library/astxcyeh(v=vs.80).aspx

Я что-то упускаю / неправильно понимаю здесь что-то действительно очевидное?

13 голосов
/ 21 октября 2010

С помощью метода расширения вы можете выполнить это:

public static class Extension
{
    public static string ToStringOrEmpty(this Object value)
    {
        return value == null ? "" : value.ToString();
    }
}

Следующее ничего не выведет на экран и не вызовет исключение:

        string value = null;

        Console.WriteLine(value.ToStringOrEmpty());
7 голосов
/ 21 октября 2010

Я не согласен с этим:

String s = myObj == null ? "" : myObj.ToString();

это взлом в любом случае. Я думаю, что это хороший пример ясного кода. Абсолютно очевидно, чего вы хотите достичь и что вы ожидаете ноль.

ОБНОВЛЕНИЕ:

Теперь я вижу, что вы не говорили, что это был взлом. Но в вопросе подразумевается, что вы думаете, что этот путь - не путь. На мой взгляд, это определенно самое ясное решение.

4 голосов
/ 21 октября 2010
string s = String.Concat(myObj);
Полагаю,

будет самым коротким способом, и при этом производительность будет незначительной. Имейте в виду, что читателю кода не совсем понятно, каково это намерение.

2 голосов
/ 21 октября 2010

Меня могут побить за ответ, но в любом случае это произойдет:

Я бы просто написал

string s = "" if (myObj! = Null) {x = myObj.toString();}

Есть ли выигрыш в производительности за использование троичного оператора?Я не знаю, насколько это возможно.

И, очевидно, как кто-то из вышеупомянутых, вы можете поместить это поведение в метод, такой как safeString (myObj), который допускает повторное использование.

2 голосов
/ 21 октября 2010

на самом деле я не понял, что ты хочешь делать.Как я понимаю, вы можете написать этот код другим способом.Вы спрашиваете это или нет?Можете ли вы объяснить больше?

string s = string.Empty;
    if(!string.IsNullOrEmpty(myObj))
    {
    s = myObj.ToString();
    }
1 голос
/ 01 декабря 2017

Некоторые (быстродействующие) тесты производительности, суммирующие различные варианты, не то, чтобы это действительно имело значение #microoptimization (с использованием linqpad extension )

Опции

void Main()
{
    object objValue = null;
    test(objValue);
    string strValue = null;
    test(strValue);
}

// Define other methods and classes here
void test(string value) {
    new Perf<string> {
        { "coallesce", n => (value ?? string.Empty).ToString() },
        { "nullcheck", n => value == null ? string.Empty : value.ToString() },
        { "str.Format", n => string.Format("{0}", value) },
        { "str.Concat", n => string.Concat(value) },
        { "string +", n => "" + value },
        { "Convert", n => Convert.ToString(value) },
    }.Vs();
}

void test(object value) {
    new Perf<string> {
        { "coallesce", n => (value ?? string.Empty).ToString() },
        { "nullcheck", n => value == null ? string.Empty : value.ToString() },
        { "str.Format", n => string.Format("{0}", value) },
        { "str.Concat", n => string.Concat(value) },
        { "string +", n => "" + value },
        { "Convert", n => Convert.ToString(value) },
    }.Vs();
}

Вероятноважно отметить, что Convert.ToString(...) сохранит пустую строку.

Результаты

Объект

  • nullcheck 1,00x 1221 тиков прошло (0,1221 мс) [в 10Kповторений, 1,221E-05 мс за]
  • Coallesce 1,14x 1387 тиков прошло (0,1387 мс) [в 10K повторений, 1,387E-05 мс за]
  • строка + 1,16x 1415 прошедших тиков(0,1415 мс) [в 10K повторениях, 1,415E-05 мс в]
  • str.Concat 1,16x 1420 тиков прошло (0,142 мс) [в 10K повторениях, 1,42E-05 мс в]
  • Преобразование 1,58x 1931 прошедших тактов (0,1931 мс) [в 10K повторений, 1,931E-05 мс за]
  • стр. Формат 5,45x 6655 промежуточных тиков (0,6655 мс) [в 10K повторений, 6,655E-05 мс за]

Строка

  • проверка нуля 1.00x 1190 тиков прошло (0.119 мс) [в 10K повторений, 1.19E-05 мс за]
  • удобстrt 1,01x 1200 тиков прошло (0,12 мс) [в 10K повторений, 1,2E-05 мс за]
  • строка + 1,04x 1239 тиков прошло (0,1239 мс) [в 10K повторений, 1,239E-05 мс за]
  • coallesce Прошло 1,20 х 1423 тиков (0,1423 мс) [в 10K повторений, 1,423E-05 мс за]
  • str.Concat 4,57x 5444 тиков прошло (0,5444 мс) [в 10Kповторений, 5.444E-05 мс на]
  • стр. Формат 5.67x 6750 прошедших тактов (0,675 мс) [в 10K повторений, 6.75E-05 мс на]
1 голос
/ 17 февраля 2015

У меня была та же проблема, и я решил ее, просто приведя объект к строке. Это работает и для нулевых объектов, потому что строки могут быть нулевыми. Если вы абсолютно не хотите иметь нулевую строку, это должно работать просто отлично:

string myStr = (string)myObj; // string in a object disguise or a null
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...