tpo*_*wer 310 c# parameters null extension-methods
是使用null值调用方法还是提供null引用异常?
MyObject myObject = null;
myObject.MyExtensionMethod(); // <-- is this a null reference exception?
Run Code Online (Sandbox Code Playgroud)
如果是这种情况,我永远不需要检查我的'this'参数是否为null?
Mar*_*ell 369
这样可以正常工作(也不例外).扩展方法不使用虚拟调用(即它使用"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);
}
Run Code Online (Sandbox Code Playgroud)
等等
从根本上说,对静态调用的调用是非常直接的 - 即
string s = ...
if(s.IsNullOrEmpty()) {...}
Run Code Online (Sandbox Code Playgroud)
变为:
string s = ...
if(YourExtensionClass.IsNullOrEmpty(s)) {...}
Run Code Online (Sandbox Code Playgroud)
哪里显然没有空检查.
Ste*_*ger 48
除了Marc Gravell的正确答案.
如果显然this参数为null,您可以从编译器收到警告:
default(string).MyExtension();
Run Code Online (Sandbox Code Playgroud)
在运行时运行良好,但会产生警告"Expression will always cause a System.NullReferenceException, because the default value of string is null"
.
Jor*_*dão 22
正如您已经发现的那样,因为扩展方法只是美化的静态方法,所以它们将null
通过传入的引用进行调用,而不会NullReferenceException
被抛出.但是,因为它们看起来像实例方法来调用者,他们也应该表现得如此.那么,您应该在大多数情况下检查this
参数并抛出异常(如果是)null
.如果方法显式处理null
值并且其名称适当地表示它,则不执行此操作,如下例所示:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
我前段时间也写了一篇博文.
Bin*_*ier 16
null将被传递给扩展方法.
如果该方法试图访问该对象而不检查它是否为null,则是,它将引发异常.
这里的一个人写了"IsNull"和"IsNotNull"扩展方法,检查是否传递null.就个人而言,我认为这是一种失常,不应该看到日常光,但它是完全有效的c#.
正如其他人所指出的那样,在null引用上调用扩展方法会导致this参数为null,并且不会发生任何其他特殊情况.这提出了使用扩展方法编写保护子句的想法.
您可以阅读本文的示例:如何减少Cyclomatic复杂性:Guard子句短版本是这样的:
public static class StringExtensions
{
public static void AssertNonEmpty(this string value, string paramName)
{
if (string.IsNullOrEmpty(value))
throw new ArgumentException("Value must be a non-empty string.", paramName);
}
}
Run Code Online (Sandbox Code Playgroud)
这是可以在null引用上调用的字符串类扩展方法:
((string)null).AssertNonEmpty("null");
Run Code Online (Sandbox Code Playgroud)
调用工作正常,因为运行时将成功调用null引用上的扩展方法.然后你可以使用这个扩展方法来实现guard子句而不会出现凌乱的语法:
public IRegisteredUser RegisterUser(string userName, string referrerName)
{
userName.AssertNonEmpty("userName");
referrerName.AssertNonEmpty("referrerName");
...
}
Run Code Online (Sandbox Code Playgroud)