Как сделать ToString для возможно нулевого объекта?


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

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

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

String s = "" + myObj;

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

11 72

11 ответов:

C# 6.0 Edit:

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

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

или еще:

string s = $"{myObj}";

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

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

или

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

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

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

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

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

public static string ToStringNullSafe(this object value)
{
    return (value ?? string.Empty).ToString();
}
string.Format("{0}", myObj);

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

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

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

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

        string value = null;

        Console.WriteLine(value.ToStringOrEmpty());

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

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

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

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

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

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

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

обновление:

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

string s = String.Concat(myObj);

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

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

string s = string.Empty;
    if(!string.IsNullOrEmpty(myObj))
    {
    s = myObj.ToString();
    }

меня могут избить за мой ответ, но здесь все равно:

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

строка s = "" если (myObj != недействительный) { x = myObj.toString(); }

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

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

комментарий Хольстебро будет вашим лучшим ответом:

string s = string.Format("{0}", myObj);

Если myObj равно null, формат помещает туда пустое строковое значение.

Он также удовлетворяет ваше однострочное требование и легко читается.

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

string myStr = (string)myObj; // string in a object disguise or a null

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

опции

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.00 x 1221 тиков прошло (0.1221 МС) [в 10K повторений, 1.221 E-05 МС в]
  • coallesce 1.14 x 1387 тиков прошло (0,1387 МС) [в 10K повторений, 1,387 E-05 МС в]
  • строка + 1.16 x 1415 тиков прошло (0.1415 МС) [в 10K повторений, 1.415 E-05 МС в]
  • str.Конкат 1.16 x 1420 тиков прошло (0.142 МС) [в 10K повторений, 1.42 E-05 МС в]
  • конвертировать 1,58 x 1931 тиков прошло (0,1931 МС) [в 10K повторений, 1,931 E-05 МС в]
  • str.Формат 5.45 x 6655 тиков прошло (0.6655 МС) [в 10K повторений, 6.655 E-05 МС Пер]

строка

  • nullcheck 1.00 x 1190 тиков прошло (0.119 МС) [в 10K повторений, 1.19 E-05 МС в]
  • конвертировать 1,01 x 1200 тиков прошло (0,12 МС) [в 10K повторений, 1,2 E-05 МС в]
  • строка + 1.04 x 1239 тиков прошло (0.1239 МС) [в 10K повторений, 1.239 E-05 МС в]
  • coallesce 1.20 x 1423 тиков прошло (0.1423 МС) [в 10K повторений, 1.423 E-05 МС в]
  • str.Concat 4.57 x 5444 тиков прошло (0.5444 ms) [in 10K reps, 5.444 e-05 ms per]
  • str.Формат 5.67 x 6750 тиков прошло (0.675 МС) [в 10K повторений, 6.75 E-05 МС в]