C# 为什么避风港';解析助手是否变得更容易使用?
鉴于.NET团队已经声明(我会找到一个来源…),他们对原语类型的解析方法的设计感到遗憾(例如),为什么没有用一个更明显的、对客户端友好的变体来更新这些方法 框架版本:C# 为什么避风港';解析助手是否变得更容易使用?,c#,parsing,language-design,nullable,deprecated,C#,Parsing,Language Design,Nullable,Deprecated,鉴于.NET团队已经声明(我会找到一个来源…),他们对原语类型的解析方法的设计感到遗憾(例如),为什么没有用一个更明显的、对客户端友好的变体来更新这些方法 框架版本: Int32? numValue; Int32 placeHolder; if (! Int32.TryParse("not a number", out placeHolder)) numValue = 10; var numValue = Int32.Parse("not a number", 10); 改进版: I
Int32? numValue;
Int32 placeHolder;
if (! Int32.TryParse("not a number", out placeHolder))
numValue = 10;
var numValue = Int32.Parse("not a number", 10);
改进版:
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;
}
此签名:
public static Int32? Parse(String s, Int32? defaultValue = null);
将与现有的Parse(string s)
重载冲突,因为如果未指定可选参数,则无法区分它们。现有方法可能永远不会被更改或删除,因为它会破坏与现有代码的兼容性
但是,可以创建TryParse
的重载,该重载不带out int值
参数:
public static int? TryParse(string s)
请注意,您不需要为默认值添加参数:您可以改用null合并运算符
string s = ...
int value = int.TryParse(s) ?? 0;
此签名:
public static Int32? Parse(String s, Int32? defaultValue = null);
将与现有的Parse(string s)
重载冲突,因为如果未指定可选参数,则无法区分它们。现有方法可能永远不会被更改或删除,因为它会破坏与现有代码的兼容性
但是,可以创建TryParse
的重载,该重载不带out int值
参数:
public static int? TryParse(string s)
请注意,您不需要为默认值添加参数:您可以改用null合并运算符
string s = ...
int value = int.TryParse(s) ?? 0;
我不确定是否会有一个明确的答案,除非BCL团队的人有故事要讲 一些考虑可能是:
TryParse
的作用int解析(字符串,int?defaultValue)
和int之间的混淆
解析(字符串)
,主要是关于它们的错误处理。通知
我已经删除了第一个方法的可选部分,否则它会
两种方法都使用没有意义(您永远无法调用
您的方法没有显式地传入null
)。在这一点上,它
当一个重载在上引发异常时,会有点混乱
失败,而另一个没有。有几个例外
对此,例如
但它们通常很少见,在这种情况下,它们使用显式命名的参数,指示它将或不会引发异常null
)
单独的真/假值。现在,一些机制可以做到这一点
(String.IndexOf
例如返回-1)因此如果
这是好事还是坏事。根据你的练习,
使用returntrue/false
值可能更容易,或者使用
magicnull
结果可能是。但他们决定我想不要弄脏了
用两种方法做完全相同的事情,但是
签名/返回值略有不同Int32?
?还是仅仅是为了
错误/输入处理?根据我的经验,可空值通常是
用于数据库I/O(即使如此,也不经常)。唯一的
其他时间可能是来自不可信来源的输入,这将
仅适用于初始接口;所有的底层代码仍然是
根据不可为空的Int32
键入。在这种情况下,你有两个
方法,原文:
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()
,如果您知道它是非空的,但很少(至少
至少从我在互联网上看到的情况来看)它是在值上使用的
存取器。如果BCL添加/更改了Parse
方法
建议,我认为很多人会不必要地打击
值
访问器
我不能特别评论使用可空值的情况
在整个应用程序设计和/或其各层中,
但根据我的经验,它们很少使用或应该很少使用(对我来说,这几乎是一种“严格类型”数据级别的代码味道)
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中已经存在的解决方法。我建议,考虑到扩展方法的选择,考虑到API的显著破坏性,更改API并不是一个大问题。除非BCL团队有人讲故事,否则我不确定是否会有一个明确的答案 一些考虑可能是: