可空的ToString()


142

我到处都看到这样的构造:

int? myVar = null;
string test = myVar.HasValue ? myVar.Value.ToString() : string.Empty;

为什么不简单使用:

string test = myVar.ToString();

那不是完全一样吗?至少Reflector说:

public override string ToString()
{
  if (!this.HasValue)
  {
    return "";
  }
  return this.value.ToString();
}

那么,这是正确的(较短的版本)还是我缺少什么?


1
我还没有看到这样的代码:)
tymtam'1

Answers:


112

你说得很对。同样在这个问题中,建议使用前一种解决方案,而实际上没有人注意到ToString()已经给出了正确的答案。

也许更冗长的解决方案的论点是可读性:当您调用应该是的ToString()东西时,通常会期望 a ,尽管这里没有抛出。nullNullReferenceException


21
实际上,至少有两个人注意到了:埃里克·利珀特(Eric Lippert)和约翰内斯·罗素(JohannesRössel)。
乔恩·斯基特

7
虽然我确定这不是您的意思,但是这里的引用实际上不是null。Nullable <T>是一个值类型。这就是为什么在调用时ToString()NullReferenceException抛出任何异常的原因。
Thorarin 2014年

2
如果那是一种心态,那么您.HasValue应该仍然会抛出该异常。
Extragorey

人们使用详细版本的另一个原因可能是为了与表达式保持一致,例如myNullableDateTime.HasValue ? myNullableDateTime.Value.ToString("d") : null您确实需要未包装的对象来访问所需的ToString方法。当然,还有一个更简洁的解决方案:$"{myNullableDateTime:d}"
Extragorey '18

14

我认为许多人都有这样的检查,因为它不是持有空值的对象的自然行为。


@Andrew表示同意,因为像我这样的人起初会认为它将引发异常。
内森·库普

1
我不知道这是行为。我绝对会认为,如果您调用x.ToString(),则任何为(x == null)返回true的构造都会抛出NullReferenceException。
丹·布莱恩特

5

不,您是正确的,简短版本与其他人在这方面所做的相同。我倾向于大量使用而不是具有可空值的三元数的另一种构造方法是null合并运算符。这也可以保护您免受null侵害。对于ToString(),这不是必须的(如您所指出的),但是对于默认的int值(例如),它可以很好地工作,例如:

int page = currentPage ?? 1;

这样一来,您就可以在不执行页面的情况下执行所有整数操作,而无需先显式进行null检查并在currentPage中调用值(其中currentPage是int?也许作为参数传递)


5

我知道,很久以前它才是相关的,但是...我怀疑这是因为像int这样的可空类型?.ToString()方法不允许您使用格式字符串。请参见如何使用ToString()格式化可为空的DateTime?。也许在原始代码中,.ToString()中有一个格式字符串,或者编码人员忘记了没有格式字符串的.ToString()在可空类型上仍然可用。


3

可能只是遵循模式吗?否则他们不知道后端。您正确的代码完全相同。您甚至可以:

int? i = null;
i.ToString(); //No NullReferenceException

如果ToString()需要具有不变的文化,则可能需要走很长的路,因为nullables在菜单中没有它。
ΕГИІИО

1

int?是语法糖,可简化可空变量的声明。与相同Nullable<int>

因此,如果您看一下ToString()for 的方法的实现Nullable<T> (请参见下文),您会注意到,如果没有值,它将返回空字符串。

public struct Nullable<T> where T : struct
{
    public override string ToString()
    {
      if (!this.hasValue)
        return "";
      return this.value.ToString();
    }
}

MSDN说:

Nullable.ToString方法

如果HasValue属性为true,则返回当前Nullable对象的值的文本表示形式;如果HasValue属性为false,则返回空字符串(“”)。

因此,以下代码将向控制台输出空字符串,而不是引发ArgumentNullException异常。

static void Main(string[] args)
{
    int? a = null;
    Console.WriteLine(a.ToString()); // Prints empty string to console.
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.