为什么T.TryParse没有返回Nullable <T>

kri*_*mog 17 .net c#

据我所知,int.TryParse(string, out int)自Framework 2.0以来就存在.那样做int?.

有没有理由使用的out参数,而不是返回一个int?HasValue设置为truefalse视转换的能力吗?

O. *_*per 21

我不知道实际的原因,但我看到三个可能的原因:

1)在.NET 2.0中引入了可空类型,而第一种TryParse方法自.NET 1.1以来就已经存在.因此,当引入可空类型时,这种API更改为时已晚; 并且新类不会以TryParse不同的方式实现,因为已经设置了模式.

2)并非所有类型都可以与Nullable结构一起使用,只有值类型可以.但是,Try*模式后面的方法必须返回引用类型.例如,字典可能完全合法地包含null为项目,因此其TryGetValue方法需要另外的方式来表示未找到密钥.

3)Try*编写-methods 的方式,可以编写如下代码:

int myValue;
if (int.TryParse("42", out myValue)) {
    // do something with myValue
}
    // do something else
}
Run Code Online (Sandbox Code Playgroud)

现在,想象一下,如果TryParse只返回一个int?.您可以处置myValue变量并丢失结果:

if (int.TryParse("42").HasValue) {
    // do something with ... what? You didn't store the conversion result!
}
    // do something else
}
Run Code Online (Sandbox Code Playgroud)

或者您可以添加一个可以为null的变量:

int? myValue = int.TryParse("42");
if (myValue.HasValue) {
    // do something with myValue.Value
}
    // do something else
}
Run Code Online (Sandbox Code Playgroud)

这不再是当前版本的优势,而是需要myValue.Value在稍后的实例中编写,否则简单value就足够了.请注意,在许多情况下,您需要有关该if语句的操作是否成功的信息.

  • @krimog为什么使用语言关键字会"不自然"? (2认同)

ana*_*der 21

原因很简单,因为何时int.TryParse添加到语言中,Nullable<T>不存在.

Eric Lippert撰写的这篇博客文章中,底部有一条线:

解决方案是编写自己的扩展方法版本的TryParse,如果首先有可用的可用值类型,它将会被编写

这清楚地表明可以在原始实现中使用可空类型TryParse.Eric Lippert是编写C#编译器的团队的成员,因此我认为这是一个非常权威的来源.

  • 再次Stackoverflow的Erik Lippert粉丝群再次罢工,只需提及Eric Lippert和即时upvotes.:d (4认同)
  • 谁*别*可以回答问题,即使他没有回答问题? (2认同)

Yuv*_*kov 5

以下是Julie Lerman博客的引用(2004年以来):

我已经玩过nullable3月的预览位,但是还没有在5月份,并且当我比较使用nullable<t>当前的选项时,当前(但是bcl团队的严重改进计划!!!)表现令人失望.例如,使用值类型:

myNullableInt.HasValue(在VB中)相比较myInt < 0

或参考类型

比较myNullableThing.HasValue" if not myThing=null"

可空类型目前要慢得多.BCL团队的一些人承诺,我的计划是让可以自由的人更加高效.

我也得到了一个暗示,将来可能会有以下几点:

Nullable<T> Parse(string value); 
Nullable<Int32> i = Int32.Parse( some String );
Run Code Online (Sandbox Code Playgroud)

而且性能会更好TryParse.所以,这也会很有趣.

认为,一如既往,效益超过了成本.

无论如何,在即将到来的C#vNext中,您可以:

DateTime.TryParse(s, out var parsedDateTime);
Run Code Online (Sandbox Code Playgroud)

将TryParse变成一个班轮.

  • 如果你不需要可空,你现在甚至可以使用单行代码:`DateTime dt = DateTime.TryParse(s,out dt)?dt:DateTime.MinValue;` (2认同)