为什么myString.IsNullOrEmpty()没有内置到.net中
本文关键字:内置 net myString IsNullOrEmpty 为什么 | 更新日期: 2023-09-27 17:50:51
有点学术性的问题,但我试图在更深层次上理解框架设计。
我们有String.IsNullOrEmpty(MyString)
和we 可以编写一个扩展方法来启用myString.IsNullOrEmpty()
,尽管这可能不是最好的主意。参见:使用IsNullOrEmpty扩展String类是否令人困惑?
所以我的问题是,为什么微软不把这个功能作为。net框架的一部分?是否有性能方面的考虑?更一般地说,为什么任何方法或属性被认为是有价值的,可以通过String对象访问,而不能作为任何String类型对象的成员使用?
静态方法String.IsNullOrEmpty
是在。net Framework 2.0版本中引入的。扩展方法是在。net框架3.5版本中与LINQ一起引入的。因此,微软在引入IsNullOrEmpty
时没有这个选项。
当然,IsNullOrEmpty
不能是String
的实例方法,因为你不能在null
的引用上调用方法。但是,您可以在这样的引用上调用扩展方法,因为扩展方法语法只是静态方法调用的语法糖。
假设IsNullOrEmpty
是一个扩展方法。然后你可以这样命名它:
string s = null;
bool result = s.IsNullOrEmpty();
在评论中,有人假装这个调用会抛出一个NullReferenceException
。扩展方法可以这样声明:
public static class StringExtensions
{
public static bool IsNullOrEmpty(this string s)
{
return s == null || s.Length == 0;
}
}
…并被这样使用…
string s = null;
bool result = s.IsNullOrEmpty();
…这只是语法糖…
string s = null;
bool result = StringExtensions.IsNullOrEmpty(s);
…因此,不会抛出异常。这样做是否是个好主意是另一个问题(见下面由usr提供的答案)。
在null
引用上调用扩展方法时不失败通常被认为是不好的做法。这是因为仅仅通过阅读代码,您无法判断是否正在调用扩展方法。你的直觉会看到调用((string)null).IsNullOrEmpty()
失败。
显然,这种方法不可能作为实例方法。所以我们违反了直觉
也就是说,我已经在我的所有重要项目中精确地定义了这个扩展,并且在很多情况下它非常有用。我愿意接受这种小程度的不纯和不直观。
框架作者显然不同意。我还认为这种方法不应该进入。net框架,因为它有点"高级",阻碍了易学性。初学者可能会问:"嗯?有时我可以安全地调用null引用上的方法,有时我不能?
因为如果您可以在空字符串上使用IsNullOrEmpty()
,那么您可能需要将该方法重命名为IsEmpty()
。
不开玩笑,方法是这样实现的:
public static bool IsNullOrEmpty(string value)
{
if (value != null)
return value.Length == 0;
else
return true;
}
很明显,对于字符串实例,条件总是为真。
还有一个小细节。以string.Concat
为例,它是一个静态方法。这本来是合理的,比如说,为什么没有相对实例方法;通过观察它的实现,我相信他们想让这些方法尽可能地万无一失。当将参数传递给方法时,在null引用的情况下,它们被替换为空字符串,而不是引发异常。当您事先不知道您的字符串实际上是否包含值或为空时,这可能很有用,我猜框架的开发人员认为,通过将空字符串视为空字符串并为最终用户节省额外的检查,从而更好地提高代码的可读性。当然,如果string.Concat
是一个实例方法(或者至少有一个替代方法),用户仍然可以传递null参数,但是正在操作的实例必须不是null。