据我所知,int.TryParse(string, out int)
自Framework 2.0以来就存在。 int?
也是如此。
是否有理由使用out
参数而不是将int?
设置为HasValue
true
false
,具体取决于转换的能力?
答案 0 :(得分:21)
我无法说出实际原因,但我认为有三个可能的原因:
1)Nullable types是在.NET 2.0中引入的,而first TryParse
methods自.NET 1.1以来就已经出现了。因此,当引入可空类型时,这种API更改为时已晚; 1}}并不会以不同的方式实现TryParse
,因为模式已经设置好了。
2)并非所有类型都可以与Nullable
structure一起使用,只有值类型可以。但是,Try*
模式后面的方法必须返回引用类型。例如,字典可能完全合法地包含null
作为项目,因此其TryGetValue
method需要另外一种方式来表示未找到密钥。
3)编写Try*
- 方法的方式,可以编写如下代码:
int myValue;
if (int.TryParse("42", out myValue)) {
// do something with myValue
}
// do something else
}
现在,假设TryParse
仅返回int?
。您可以处置myValue
变量并丢失结果:
if (int.TryParse("42").HasValue) {
// do something with ... what? You didn't store the conversion result!
}
// do something else
}
或者你可以添加一个可以为空的变量:
int? myValue = int.TryParse("42");
if (myValue.HasValue) {
// do something with myValue.Value
}
// do something else
}
这不再是当前版本的优势,而是需要在稍后的某些实例中编写myValue.Value
,否则简单的value
就足够了。请注意,在许多情况下,仅需要有关if
语句操作是否成功的信息。
答案 1 :(得分:21)
原因很简单,因为当int.TryParse
添加到语言中时,Nullable<T>
不存在。
在this blog post by Eric Lippert中,底部有一条线:
解决方案是编写自己的扩展方法版本的TryParse,就像在第一时间可用的可空值类型一样编写它
明确指出可以在TryParse
的原始实现中使用可空类型。 Eric Lippert是编写C#编译器的团队,因此我认为这是一个非常权威的来源。
答案 2 :(得分:5)
这里引用了Julie Lerman的博客(从2004年开始):
我在3月的预览位中使用了
nullable
,但是在5月份还没有玩过,并且当我比较使用时,对当前(但是bcl团队的严重改进)的表现感到失望。 {1}}当前选项。例如,使用值类型:将
nullable<t>
与(在VB中)比较为myNullableInt.HasValue
或参考类型
将
myInt < 0
与“myNullableThing.HasValue
”进行比较可空类型目前要慢得多。 BCL团队的一些人承诺承诺可以让可以自由的更高效率。
我也得到了一个暗示,将来可能会有以下几点:
if not myThing=null
并且比
Nullable<T> Parse(string value); Nullable<Int32> i = Int32.Parse( some String );
更高效。所以,这也很有趣。
我假设一如既往,好处超过了成本。
无论如何,在即将推出的C#vNext中,您可以这样做:
TryParse
将TryParse变成一个单线。
答案 3 :(得分:4)
另一个可能的原因:
当前形式的.NET和C#的泛型几乎没有发生:这是一个非常接近的调用,并且该功能几乎没有为Whidbey(Visual Studio 2005)做出决定。诸如在数据库上运行CLR代码等功能被赋予了更高的优先级。
...
最终,对于Java来说,将采用泛型的擦除模型,因为CLR团队在没有外部帮助的情况下永远不会追求虚拟机内的泛型设计。
我的观点是:BCL中的大多数更改(或者至少那些直接与泛型有关的更改)可能需要同时使用使用和不使用泛型,该特征在最终的RTM中被删除的情况。
当然,从主叫客户的角度来看,这也是有意义的:所有消费语言(好的,当时没有多少人)理想情况下能够使用它们 - 以及out
个参数并不像普通人那样具有前沿性。
答案 4 :(得分:3)
至于我们只能猜测的原因,但一些可能的原因是:
分配开销:盒装值会比内置类型产生一些(小)性能开销。
没有真正的收获:
int res;
if int.TryParse("one", out res) {
//something
}
并不比
差int? res = int.TryParse("one");
if (res.HasValue){
int realres = res.Value
//something
}