一些学术问题,但我试图在更深层次上理解框架设计。
所以我们有String.IsNullOrEmpty(MyString)
我们可以编写一个扩展方法来启用myString.IsNullOrEmpty()
,尽管这可能不是最好的主意。请参阅:Is extending String class with IsNullOrEmpty confusing?。
所以我的问题是,为什么MS不将此功能写为.Net框架的一部分?有一些性能考虑因素吗?更一般地说,为什么任何方法或属性被视为有价值,可以通过String对象构建为不可用作为字符串类型的任何对象的成员?
答案 0 :(得分:31)
静态方法String.IsNullOrEmpty
是在.NET Framework 2.0版中引入的。与.NETQ一起在.NET Framework 3.5版中引入了扩展方法。因此,在引入IsNullOrEmpty
时,Microsoft没有此选项。
当然,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);
...因此,不会抛出异常。这是否是一个好主意是另一个问题(见answer provided by usr below)。
答案 1 :(得分:21)
在null
引用上调用扩展方法时,通常认为是不好的做法。这是因为仅仅通过阅读代码就无法判断是否正在调用扩展方法。你的直觉是看到电话((string)null).IsNullOrEmpty()
失败。
显然,这种方法不可能作为实例方法。所以我们在这里违反了直觉。
也就是说,我已经在我的所有重要项目中确切地定义了这个扩展,并且在很多情况下它非常有用。我愿意接受这种微小的杂质和不直观。
框架作者显然不同意。我也认为这种方法不应该进入.NET Framework,因为它有点“高级”并且阻碍了可学习性。一个初学者可能会问“嗯?有时候我可以安全地调用null引用上的方法,有时我不能?怎么分辨?”。
答案 2 :(得分:6)
因为如果你可以在空字符串上使用IsNullOrEmpty()
,那么你可能想要将方法重命名为IsEmpty()
。
除了笑话,这就是方法的实施方式:
public static bool IsNullOrEmpty(string value)
{
if (value != null)
return value.Length == 0;
else
return true;
}
很明显,在字符串实例的情况下,条件总是如此。
另外,一个小细节。例如,string.Concat
这是一种静态方法。例如,它可能是合理的,想知道为什么没有相对实例方法;通过查看其实现,我相信他们希望尽可能地使这些方法成为失败证明。将参数传递给方法时,如果是空引用,则将它们替换为空字符串,而不是抛出异常。当你事先不知道你的字符串是否实际包含一个值或者为null时,这可能很有用,我猜这个框架的开发人员认为通过处理空字符串来提高代码可读性会更好作为空的并保存最终用户额外的检查。当然,如果string.Concat
是一个实例方法(或至少有一个替代方法),用户仍然可以传递空参数,但正在操作的实例必然不为空。