为什么允许null对象的扩展方法?
允许在null对象上调用扩展方法有什么意义? 这让我不必要地检查扩展方法中的null对象。 AFAIK,我无法理解这一点? 请解释。
扩展方法是C#语言的语法糖,它们被编译为ILCode中的常规静态方法调用。 静态方法在编译时对参数一无所知。
简单地说,为什么不呢?
如果您在扩展中调用的第一个方法也会抛出正确的错误,您有时可以跳过测试。
你基本上要求代码不同,以便:
- 对空对象使用合理的使用将被禁止。
- 使用不需要空检查(因为它隐含在其他东西中)会得到您想要自动发生的不必要检查的开销。
这似乎很多其他用途只是为了保存以下一行:
if(arg == null)throw new ArgumentNullException();
扩展方法只是语法糖。 实际上它们是另一个类的静态方法,所以既然你可以写
IEnumerable foo = null; Enumerable.Count(foo);
你也可以写
IEnumerable foo = null; foo.Count();
有时,允许在null对象上调用扩展方法,允许您将null检查移动到方法而不是调用站点,从而简化了代码。 例如,您可能有一个返回List
的扩展方法,但如果在null对象上调用,则返回一个空的List
。
- 扩展方法转换为静态方法调用,因此代码仍然需要检查空参数,因为没有方法可以避免在没有扩展方法语法糖的情况下正常调用静态方法。
- 添加类似支票后跟
NullArgumentException
类的东西可能需要执行时间,用户可能想要断言或使用其他东西。 - 它会使替换更复杂,无法解释或自动执行,因为使用相应的静态方法调用简单替换扩展方法将改变代码的行为。
- 在合法的情况下,您希望允许空参数(对于从对象模型到另一种类型的空对象转换为第二种类型的空对象的另一种转换)
扩展方法只是静态方法:
List x = null; x.Count()
相当于:
List x = null; System.Linq.EnumerableExtensions.Count(x); //EnumerableExtensions may not be the class, but you get the idea
另一个不可能的美丽例子:
public static bool IsNullOrEmpty(this string value) { return string.IsNullOrEmpty(value); }
所以你可以使用
string s = null; if (s.IsNullOrEmpty()) // no null reference error! ...
代替
string s = null; if (string.IsNullOrEmpty(s)) ....