为什么myString.IsNullOrEmpty()没有内置到.Net中?

Fau*_*ust 19 .net c#

这是一个学术问题,但我试图在更深层次上理解框架设计.

所以我们有 String.IsNullOrEmpty(MyString)

我们可以编写一个扩展方法来启用myString.IsNullOrEmpty(),尽管这可能不是最好的想法.请参阅:使用IsNullOrEmpty扩展String类是否令人困惑?.

所以我的问题是,为什么MS不将此功能写为.Net框架的一部分?有一些性能考虑因素吗?更一般地说,为什么任何被视为有价值的方法或属性都可以通过String对象构建为不可用作为字符串类型的任何对象的成员?

Oli*_*bes 34

静态方法String.IsNullOrEmpty是在.NET Framework 2.0版中引入的.与.NETQ一起在.NET Framework 3.5版中引入了扩展方法.因此,Microsoft在介绍时没有此选项IsNullOrEmpty.

当然,IsNullOrEmpty不能是一个实例方法String,因为你不能在引用上调用一个方法null.但是,您可以在此类引用上调用扩展方法,因为扩展方法语法只是静态方法调用的语法糖.


我们假设这IsNullOrEmpty是一种扩展方法.然后你可以这样称呼它:

string s = null;
bool result = s.IsNullOrEmpty();
Run Code Online (Sandbox Code Playgroud)

在评论中,有人假装这个电话会抛出一个NullReferenceException.扩展方法将声明如下:

public static class StringExtensions
{
    public static bool IsNullOrEmpty(this string s)
    {
        return s == null || s.Length == 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

......并且像这样使用......

 string s = null;
 bool result = s.IsNullOrEmpty();
Run Code Online (Sandbox Code Playgroud)

......这只是...的语法糖

 string s = null;
 bool result = StringExtensions.IsNullOrEmpty(s);
Run Code Online (Sandbox Code Playgroud)

......因此,不会抛出异常.这样做是否是一个好主意是另一个问题(见下面usr提供的答案).


usr*_*usr 23

在引用上调用扩展方法时,通常认为是不好的做法null.这是因为仅仅通过阅读代码就无法判断是否正在调用扩展方法.你的直觉是看到呼叫((string)null).IsNullOrEmpty()失败.

显然,这种方法不可能作为实例方法.所以我们在这里违反了直觉.

也就是说,我已经在我的所有重要项目中确切地定义了这个扩展,并且在很多情况下它非常有用.我愿意接受这种微小的杂质和不直观.

框架作者显然不同意.我还认为这种方法不应该进入.NET Framework,因为它有点"高级"并且妨碍了可学习性.初学者可能会问"嗯?有时候我可以安全地调用null引用上的方法,有时我不能?怎么分辨?".

  • 阻碍可学习性也是一个很好的论据.多年来,C#变得非常复杂.有些人倾向于拒绝不使用LINQ或扩展方法的每个解决方案,但"经典"解决方案仍然很好. (2认同)
  • 这是一个很好的答案.我选择**不是**违反我的直觉,并继续调用静态方法,意思是`String.IsNullOrEmpty(my_variable)`.我只是不同意"A*初学者*可能会问".不不不!**.不仅****"初学者".**任何人**都可以提出这个问题.任何人.如果你问我,我会说"任何人,特别是一个多语言程序员,他们已经到了这里,并且不能再看到任何更多的例外 - 必须记住的规则的快捷方式和任何更多的变量称为"结果"或"tmp"." 然后我会砰地关上键盘.所以,不要问我. (2认同)

Mir*_*Mir 6

因为如果你可以使用IsNullOrEmpty()空字符串,那么你可能想要将方法重命名为IsEmpty().

除了笑话,这是方法的实现方式:

public static bool IsNullOrEmpty(string value)
{
  if (value != null)
    return value.Length == 0;
  else
    return true;
}
Run Code Online (Sandbox Code Playgroud)

很明显,在字符串实例的情况下,条件总是如此.

还有,一个小细节.例如,string.Concat这是一种静态方法.例如,它可能是合理的,想知道为什么没有相对实例方法; 通过查看其实现,我相信他们希望尽可能地使这些方法成为失败证明.将参数传递给方法时,如果是空引用,则将它们替换为空字符串,而不是抛出异常.当你事先不知道你的字符串是否实际包含一个值或者为null时,这可能很有用,我猜这个框架的开发人员认为通过处理空字符串来提高代码可读性会更好作为空的并保存最终用户额外的检查.当然,如果string.Concat是一个实例方法(或者至少有一个替代方法),用户仍然可以传递空参数,但正在操作的实例必然不为空.