web-dev-qa-db-ja.com

nullの可能性があるオブジェクトに対してToStringを実行する方法は?

以下を行う簡単な方法はありますか?

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

私は次のことができることを知っていますが、私はそれをハックと本当に考えています:

String s = "" + myObj;

Convert.ToString()がこのための適切なオーバーロードを持っていると素晴らしいでしょう。

79
codymanix

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();
}
148
Andrew Hanlon
string.Format("{0}", myObj);

string.Formatは、nullを空の文字列としてフォーマットし、null以外のオブジェクトでToString()を呼び出します。私が理解しているように、これはあなたが探していたものです。

40
Holstebroe

Convert.ToString()がこのための適切なオーバーロードを持っていると素晴らしいでしょう。

.Net 2.0以降(このQが尋ねられる約5年前)からConvert.ToString(Object value)があります。

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

ここで本当に明白な何かを見逃している/誤解していますか?

14
Rob Gilliam

拡張メソッドを使用すると、これを実現できます。

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

以下は画面に何も書き込まず、例外をスローしません。

        string value = null;

        Console.WriteLine(value.ToStringOrEmpty());
13

私はこれに反対します:

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

何らかの方法でハックです。明確なコードの良い例だと思います。何を達成したいのか、そしてnullを期待しているのは明らかです。

更新:

あなたはこれがハックだと言っていなかったことがわかりました。しかし、あなたはこの方法が進むべき道ではないと思うという質問に暗示されています。私の考えでは、それは間違いなく最も明確なソリューションです。

7
steinar
string s = String.Concat(myObj);

私が推測する最短の方法であり、パフォーマンスのオーバーヘッドも無視できます。コードの読者にとって、意図が何であるかは明確ではありませんが、覚えておいてください。

4
herzmeister

実際、私はあなたが何をしたいのか理解できませんでした。私が理解しているように、このような別の方法でこのコードを書くことができます。あなたはこれを求めていますか?もっと説明してもらえますか?

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

私は答えを得るためにbeatられるかもしれませんが、とにかくここに行きます:

私は単に書くだろう

文字列s = "" if(myObj!= null){x = myObj.toString(); }

三項演算子を使用した場合のパフォーマンスの観点から見返りはありますか?私は頭のてっぺんから知らない。

そして明らかに、上記の誰かが述べたように、この動作をsafeString(myObj)などの再利用可能なメソッドに入れることができます。

2
jaydel

Holstebroeのコメントがあなたの最良の答えでしょう。

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

myObjがnullの場合、Formatはそこに空の文字列値を配置します。

また、1行の要件を満たし、読みやすくなっています。

1
jp2code

さまざまなオプションを要約したいくつかの(速度)パフォーマンステスト。実際には重要ではない#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(...)はnull文字列を保持することを指摘することがおそらく重要です。

結果

対象

  • nullcheck 1.00x 1221ティック経過(0.1221ミリ秒)[10K担当者、1.221E-05ミリ秒]
  • 結合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ミリ秒あたり]
  • str.Format 5.45x 6655ティック経過(0.6655ミリ秒)[10K担当者、6.655E-05ミリ秒]

ひも

  • nullcheck 1.00x 1190ティック経過(0.119ミリ秒)[10K担当者、1.19E-05ミリ秒]
  • 経過した1.01x 1200ティックを変換します(0.12ミリ秒)[1万回の繰り返しで、1.2E-05ミリ秒]
  • 文字列+ 1.04x 1239ティック経過(0.1239ミリ秒)[10K担当者、1.239E-05ミリ秒]
  • 結合1.20x 1423ティック経過(0.1423ミリ秒)[10K担当者、1.423E-05ミリ秒あたり]
  • str.Concat 4.57x 5444ティック経過(0.5444ミリ秒)[10K担当者、5.444E-05ミリ秒あたり]
  • str.Format 5.67x 6750 ticks経過(0.675ミリ秒)[10K担当者、6.75E-05ミリ秒]
1
drzaus

私は同じ問題を抱えていて、オブジェクトを文字列にキャストするだけで解決しました。これは、文字列がnullになる可能性があるため、nullオブジェクトでも機能します。 null文字列を絶対に使いたくない場合を除き、これはうまく機能するはずです。

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

これは古い質問であり、OPはC#を要求しましたが、C#ではなくVB.Netで作業する人のためにVB.Netソリューションを共有したいと思います。

Dim myObj As Object = Nothing
Dim s As String = If(myObj, "").ToString()

myObj = 42
s = If(myObj, "").ToString()

残念ながら、VB.Netでは変数の後に?演算子を使用できないため、myObj?.ToStringは無効です(少なくとも、ソリューションのテストに使用した.Net 4.5では無効です)。代わりに、Ifを使用して、myObjがNothingの場合に空の文字列を返します。したがって、最初のTostring-Callは空の文字列を返し、2番目(myObjがNothingではない)は「42」を返します。

0
Sascha