为什么允许null对象的扩展方法?

时间:2011-03-28 13:09:19

标签: c# extension-methods

允许在null对象上调用扩展方法有什么意义? 这让我不必要地检查扩展方法中的null对象。 AFAIK,我无法理解这一点? 请解释一下。

7 个答案:

答案 0 :(得分:31)

扩展方法是C#语言的语法糖,它们被编译为ILCode中的常规静态方法调用。静态方法在编译时对参数一无所知。

答案 1 :(得分:16)

简单地说,为什么不呢?

如果您在扩展程序中调用的第一个方法也会抛出正确的错误,您有时可以跳过测试。

你基本上要求代码不同,以便:

  1. 在空对象上使用合理的内容,将被禁止使用。
  2. 使用不需要空检查(因为它隐含在其他内容中)会得到您想要自动进​​行的不必要检查的开销。
  3. 对于其他用途来说,这似乎很多只是为了保存以下一行:

    if(arg == null)throw new ArgumentNullException();
    

答案 2 :(得分:8)

扩展方法只是语法糖。实际上它们是另一个类的静态方法,所以既然你可以写

IEnumerable<int> foo = null;
Enumerable.Count(foo);

你也可以写

IEnumerable<int> foo = null;
foo.Count();

答案 3 :(得分:2)

有时,允许在null对象上调用扩展方法,允许您将null检查移动到方法而不是调用站点,从而简化了代码。例如,您可能有一个返回List<T>的扩展方法,但如果在null对象上调用,则返回空List<T>

答案 4 :(得分:1)

  1. 扩展方法被转换为静态方法调用,因此代码仍然需要检查null参数,因为没有办法避免在没有扩展方法语法糖的情况下正常调用静态方法。
  2. 添加类似支票后跟NullArgumentException的内容可能需要执行时间,用户可能想要断言或使用其他内容。
  3. 由于使用相应的静态方法调用简单替换扩展方法会改变代码的行为,这会使替换更复杂,无法解释或自动执行。
  4. 在合法的情况下,您希望允许空参数(对于从对象模型到另一种类型的空对象转换为第二种类型的空对象的另一种转换)

答案 5 :(得分:1)

扩展方法只是静态方法:

List<int> x = null;
x.Count()

相当于:

List<int> x = null;
System.Linq.EnumerableExtensions.Count(x); 
//EnumerableExtensions may not be the class, but you get the idea

答案 6 :(得分:1)

另一个美好的例子,否则是不可能的:

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))
    ....