为什么哈文';解析帮助程序变得更容易使用
本文关键字:易使用 帮助程序 哈文 为什么 | 更新日期: 2023-09-27 17:57:37
给定。NET团队表示(我会找到消息来源…),他们对基元类型的解析方法(例如Int32.TryParse(String s, out Int32 result)
)的设计感到遗憾,为什么没有用更明显、更适合客户端的变体来更新这些方法?
框架版本:
Int32? numValue;
Int32 placeHolder;
if (! Int32.TryParse("not a number", out placeHolder))
numValue = 10;
改进版本:
var numValue = Int32.Parse("not a number", 10);
改进解析方法的签名是:
public static Int32? Parse(String s, Int32? defaultValue = null);
它可能有一个天真的实现:
public static Int32? Parse(String s, Int32? defaultValue = null) {
Int32 temp;
return ! Int32.TryParse(s, out temp)
? defaultValue
: temp;
}
我不确定会有一个明确的答案,除非BCL团队的人有故事要讲。
一些考虑因素可能是:
- 更改方法将构成对现有的代码库几乎没有(如果有的话)收益。一些可能会辩称,由于以下原因,这将是一种损害
- Nullable types
框包装的包装导致(轻微)性能下降的基础值即使您希望解析成功,但不希望可以为null的类型 - 如果您知道您的输入被认为是有效的,那么
Parse
方法为输入的异常情况抛出异常无效。这通常更具表演性,因为我们没有额外的当我们不需要时的错误处理代码设计观点。如果你打算处理无效案件,这就是TryParse
的作用 int Parse(string, int? defaultValue)
和int Parse(string)
之间的混淆,主要是关于它们的错误处理。注意我已经删除了第一个方法的可选部分,否则它会同时拥有两个方法是没有意义的(您永远无法调用您的方法而不显式传递null
)。在这一点上当一个重载在而另一个没有。有几个例外对此,例如类型GetType但它们通常是罕见的,在这种情况下,它们使用显式命名的参数,指示其将或不会抛出异常TryParse
设计的另一个好处是它非常漂亮通过其API来显式地处理通过/失败结果。相当地而不是指示失败的幻数/结果(null
),则返回单独的真/假值。现在,一些机制可以做到这一点(例如String.IndexOf
返回-1),因此如果这是好事还是坏事。根据您的实践,使用返回的true/false
值可能更容易,或者使用神奇的null
结果可能是。但他们决定我想不要搅乱两种方法的水域做着完全相同的事情,但签名/返回值略有不同-
另一个考虑因素是可为null的值类型有多常见。是你真的在很多地方使用
Int32?
吗?还是只是为了错误/输入处理?根据我的经验,可为null的值大多是用于数据库I/O(即使在那时,也不经常)。唯一其他时间可能是来自不可信来源的输入仅用于初始接口;所有底层代码仍然针对不可为null的CCD_ 13键入。在这种情况下,你有两个方法,原始:int input; if (TryParse(someString, out input)) DoSomethingValid(input); //valid! Do something else ErrorMessage()//not valid, error!
或者你的建议:
int? input = Parse(someString) if (input != null) DoSomethingValid(input.GetValueOrDefault())//valid! Do something else ErrorMessage()//not valid, error!
请注意和是多么相似。你的建议真的提供了如果说这件事有什么不同的话。还要注意的用法
GetValueOrDefault()
,这是实际上访问包装值的更快/更好的方法,如果您知道它不是null,但很少(在至少从我在互联网上看到的)它是在Value
上使用的吗访问者。如果BCL添加/更改了Parse
方法建议,我认为很多的人会不必要地打CCD_ 17接入器。我不能特别评论使用可为null值的情况显著地贯穿应用程序设计和/或其层,但根据我的经验,它们很少使用或应该很少使用(对我来说,这几乎是"字符串类型"数据级别的代码气味)
最终,我认为添加扩展方法(除了Linq)的原因中的部分是为了允许用户根据需要推出自己的API。在您的情况下,您可以轻松地添加一个扩展方法来获得您想要的语法:
public static Int32? Parse(this String s, Int32? defaultValue = null)
{
Int32 temp;
return !Int32.TryParse(s, out temp)
? defaultValue
: temp;
}
string validString = "1";
int? parsed = validString.Parse(); //1
int? failParsed = "asdf".Parse(9); //9
团队通常倾向于维持现状,添加必须提供足够大的效益才能添加到系统中,团队还考虑API as-is中已经存在的解决方案。我建议,考虑到API的显著破坏性,考虑到扩展方法选项,改变它并不是一个大问题。
此签名:
public static Int32? Parse(String s, Int32? defaultValue = null);
将与现有的Parse(string s)
重载冲突,因为如果未指定可选参数,则无法区分它们。现有的方法可能永远不会被更改或删除,因为这会破坏与现有代码的兼容性。
然而,可以创建不带out int value
参数的TryParse
过载:
public static int? TryParse(string s)
请注意,您不需要为默认值添加参数:您可以使用null合并运算符。
string s = ...
int value = int.TryParse(s) ?? 0;