如何为一个可能为空的对象做 ToString?

有没有一种简单的方法可以做到以下几点:

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

我知道我可以做到以下几点,但我真的认为这是一种黑客行为:

String s = "" + myObj;

如果 Convert.ToString ()对此有一个适当的重载,那就太好了。

127893 次浏览
string.Format("{0}", myObj);

绳子。Format 将把 null 格式化为空字符串,并对非 null 对象调用 ToString ()。据我所知,这就是你要找的东西。

其实我不明白你想做什么。据我所知,您可以用另一种方式编写这段代码。你到底要不要问?你能再解释一下吗?

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

使用扩展方法,您可以完成以下任务:

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

下面的代码不会向屏幕写入任何内容,也不会抛出异常:

        string value = null;


Console.WriteLine(value.ToStringOrEmpty());

C # 6.0编辑:

使用 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()

Therefore, while it maybe appears elegant, the cast is almost always necessary and is not that succinct in practice.

正如其他地方建议的那样,我建议也许可以使用扩展方法来使这个过程更简洁:

public static string ToStringNullSafe(this object value)
{
return (value ?? string.Empty).ToString();
}

我不同意这一点:

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

不管怎样都是黑客。我认为这是清晰代码的一个很好的例子。您想要实现的目标是显而易见的,并且您期望为空。

更新:

我现在明白了,你不是说这是黑客行为。但是这个问题暗示了你认为这条路走不通。在我看来,这绝对是最清楚的解决办法。

Holstebroe's comment would be your best answer:

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

如果 myObj为 null,则 Format 在其中放置一个空字符串值。

它也满足您的一行的要求,并很容易阅读。

我可能会因为自己的回答而挨揍,但不管怎样,我还是要说:

我只会写信

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

使用三元运算符在性能方面是否有回报?我一下子不知道。

And clearly, as someone above mentioned, you can put this behavior into a method such as safeString(myObj) that allows for reuse.

string s = String.Concat(myObj);

将是最短的方式,我想,也有可忽略的性能开销。请记住,尽管对于代码的读者来说,它的意图是什么并不十分清楚。

It would be great if Convert.ToString() had a proper overload for this.

之后就有了 Convert.ToString(Object value)。Net 2.0(在这个问题被提出之前大约5年) ,它看起来完全符合你的需要:

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

我是不是误解了什么很明显的东西?

I had the same problem and solved it by simply casting the object to string. This works for null objects too because strings can be nulls. Unless you absolutely don't want to have a null string, this should work just fine:

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.1221次滴答运行(0.1221 ms)[以10K 次计,1.221E-05 ms/次]
  • 1.14 x 1387刻度(0.1387毫秒)[每10K 次,1.387E-05毫秒]
  • 字符串 + 1.16 x 1415秒(0.1415 ms)[以10K 为单位,1.415E-05 ms/]
  • 连接1.16 x 1420次滴答(0.142毫秒)[以10K 次计,每次1.42E-05毫秒]
  • 转换1.58 x 1931秒经过(0.1931毫秒)[以10K 次计,1.931E-05毫秒/次]
  • Str 格式5.45 x 6655刻度(0.6655毫秒)[每10K 次,6.655E-05毫秒]

绳子

  • Nullcheck 1.00.1190经过(0.119 ms)[以10K 次计,1.19E-05 ms/次]
  • 转换1.01 x 1200秒(0.12毫秒)[每10K 次,1.2E-05毫秒]
  • 字符串 + 1.04 x 1239次滴答(0.1239 ms)[以10K 为单位,1.239E-05 ms/]
  • 共聚1.20.1423次(0.1423毫秒)[以10K 次计,1.423E-05毫秒/次]
  • 连接4.57 x 5444次滴答(0.5444毫秒)[每10K 次,5.444E-05毫秒]
  • Str 格式5.67 x 6750刻度(0.675毫秒)[每10K 次,6.75E-05毫秒]

尽管这是一个老问题,而且 OP 要求使用 C # ,我还是想为那些使用 VB.Net 而不是 C # 的人分享一个 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 ist Nothing。因此,第一个 Tostring-Call 返回一个空字符串,而第二个(其中 myObj 不是 Nothing)返回“42”。