简体   繁体   English

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

[英]why allow extension methods on null objects?

what is the point of allowing invocation of extension methods on null objects? 允许在null对象上调用扩展方法有什么意义? this is making me unnecessarily check for a null object in the extension method. 这让我不必要地检查扩展方法中的null对象。 AFAIK,i can't understand this? AFAIK,我无法理解这一点? Please explain. 请解释。

Extension methods are syntactic sugar of the C# language, they get compiled to normal static method calls in ILCode. 扩展方法是C#语言的语法糖,它们被编译为ILCode中的常规静态方法调用。 A static method doesn't know anything about the parameters at compile time. 静态方法在编译时对参数一无所知。

Simply put, why not? 简单地说,为什么不呢?

You can sometimes skip the test if the first method you call within the extension would also throw the correct error. 如果您在扩展中调用的第一个方法也会抛出正确的错误,您有时可以跳过测试。

You're essentially asking for the code to be different so that: 你基本上要求代码不同,以便:

  1. Uses which are reasonable on a null object, become disallowed. 对空对象使用合理的使用将被禁止。
  2. Uses which don't need a null check (because it's implicit in something else) get the overhead of the needless check you want to happen automatically. 使用不需要空检查(因为它隐含在其他东西中)会得到您想要自动发生的不必要检查的开销。

This seems a lot of an imposition on other uses just to save the one line of: 这似乎很多其他用途只是为了保存以下一行:

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

Extension methods are just syntactic sugar. 扩展方法只是语法糖。 In reality they are static methods on another class, so since you can write 实际上它们是另一个类的静态方法,所以既然你可以写

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

You can also write 你也可以写

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

Sometimes, allowing the extension method to be called on a null object simplifies your code by allowing you to move the null check into the method instead at the call site. 有时,允许在null对象上调用扩展方法,允许您将null检查移动到方法而不是调用站点,从而简化了代码。 For example, you may have an extension method that returns a List<T> , but if called on a null object, returns an empty List<T> . 例如,您可能有一个返回List<T>的扩展方法,但如果在null对象上调用,则返回一个空的List<T>

Another beautiful example that wouldn't be possible otherwise: 另一个不可能的美丽例子:

public static bool IsNullOrEmpty(this string value)
{
    return string.IsNullOrEmpty(value);
}

So you can use 所以你可以使用

string s = null;
if (s.IsNullOrEmpty()) // no null reference error!
    ...

Instead of 代替

string s = null;
if (string.IsNullOrEmpty(s))
    ....
  1. Extension methods are transformed to static method invocations so the code will still need to check for null arguments as there is no way to avoid the static method to be called normally without the extension method syntactic sugar. 扩展方法被转换为静态方法调用,因此代码仍然需要检查空参数,因为没有方法可以避免在没有扩展方法语法糖的情况下正常调用静态方法。
  2. Adding something like a check followed by a NullArgumentException could take execution time and the user may want to assert instead or use something else. 添加类似支票后跟NullArgumentException类的东西可能需要执行时间,用户可能想要改为断言或使用其他东西。
  3. It would make the replacement more complex to explain or do automatically as the simple replacement of the extension method with the corresponding static method call will change the behavior of the code. 它会使替换更复杂,无法解释或自动执行,因为使用相应的静态方法调用简单替换扩展方法将改变代码的行为。
  4. There are legitimate case where you want to allow null arguments (for exemple conversions from an object model to another where a null object of one type is converted to a null object of the second type) 在合法的情况下,您希望允许空参数(对于从对象模型到另一种类型的空对象转换为第二种类型的空对象的另一种转换)

Extension methods are just static methods: 扩展方法只是静态方法:

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

Is equivalent to: 相当于:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM