该方法是使用空值调用还是给出空引用异常?

MyObject myObject = null;
myObject.MyExtensionMethod(); // <-- is this a null reference exception?

如果是这样的话,我将永远不需要检查我的“this”参数为空?


当前回答

当你想让你的文章具有可读性和垂直性时,很少有黄金法则。

值得一提的是,Eiffel说封装到方法中的特定代码应该针对某些输入工作,如果满足某些先决条件并确保预期输出,那么代码是可行的

在你的情况下 -设计合同被打破了…您将在一个空实例上执行一些逻辑。

其他回答

As you've already discovered, since extension methods are simply glorified static methods, they will be called with null references passed in, without a NullReferenceException being thrown. But, since they look like instance methods to the caller, they should also behave as such. You should then, most of the time, check the this parameter and throw an exception if it's null. It's OK not to do this if the method explicitly takes care of null values and its name indicates it duly, like in the examples below:

public static class StringNullExtensions { 
  public static bool IsNullOrEmpty(this string s) { 
    return string.IsNullOrEmpty(s); 
  } 
  public static bool IsNullOrBlank(this string s) { 
    return s == null || s.Trim().Length == 0; 
  } 
}

前段时间我也写过一篇关于这方面的博文。

除了Marc Gravell的正确答案。

如果this参数明显为null,你可能会从编译器得到警告:

default(string).MyExtension();

在运行时运行良好,但产生警告“Expression将始终导致System. exe”。NullReferenceException,因为string的默认值是null"。

extensionmethod是静态的,所以如果你不给这个MyObject添加任何东西,这应该不是问题,一个快速的测试应该可以验证它:)

当你想让你的文章具有可读性和垂直性时,很少有黄金法则。

值得一提的是,Eiffel说封装到方法中的特定代码应该针对某些输入工作,如果满足某些先决条件并确保预期输出,那么代码是可行的

在你的情况下 -设计合同被打破了…您将在一个空实例上执行一些逻辑。

这将工作得很好(没有例外)。扩展方法不使用虚拟调用(即它使用“call”il指令,而不是“callvirt”),所以没有空检查,除非你自己在扩展方法中写它。这实际上在一些情况下是有用的:

public static bool IsNullOrEmpty(this string value)
{
    return string.IsNullOrEmpty(value);
}
public static void ThrowIfNull<T>(this T obj, string parameterName)
        where T : class
{
    if(obj == null) throw new ArgumentNullException(parameterName);
}

etc

从根本上说,对静态调用的调用是非常字面化的。

string s = ...
if(s.IsNullOrEmpty()) {...}

就变成:

string s = ...
if(YourExtensionClass.IsNullOrEmpty(s)) {...}

这里显然没有空检查。