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);
}
等等
从根本上说,对静态呼叫的呼叫是非常直接的 - 即
string s = ...
if(s.IsNullOrEmpty()) {...}
变为:
string s = ...
if(YourExtensionClass.IsNullOrEmpty(s)) {...}
哪里显然没有空检查 .
-1
Addition to the correct answer from Marc Gravell.
如果显然this参数为null,您可以从编译器收到警告:
default(string).MyExtension();
在运行时运行良好,但会产生警告 "Expression will always cause a System.NullReferenceException, because the default value of string is null" .
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);
}
}
7 回答
这样可以正常工作(也不例外) . 扩展方法不使用虚拟调用(即它使用“call”il指令,而不是“callvirt”),因此除非您在扩展方法中自己编写,否则不会进行空值检查 . 在少数情况下,这实际上很有用:
等等
从根本上说,对静态呼叫的呼叫是非常直接的 - 即
变为:
哪里显然没有空检查 .
Addition to the correct answer from Marc Gravell.
如果显然this参数为null,您可以从编译器收到警告:
在运行时运行良好,但会产生警告
"Expression will always cause a System.NullReferenceException, because the default value of string is null"
.正如您已经发现的那样,因为扩展方法只是美化的静态方法,所以在传入
null
引用的情况下调用它们,而不会抛出NullReferenceException
. 但是,因为它们看起来像调用者的实例方法,所以它们也应该这样 . 那么,您应该在大多数情况下检查this
参数并在其为null
时抛出异常 . 如果方法显式处理null
值并且其名称适当地表示它,则不执行此操作,如下例所示:我前段时间也写了这个.2451424_ .
null将被传递给扩展方法 .
如果该方法试图访问该对象而不检查它是否为null,则是,它将引发异常 .
这里的一个人写了“IsNull”和“IsNotNull”扩展方法,检查是否传递null . 就个人而言,我认为这是一种失常,不应该看到日常光,但它是完全有效的c# .
正如其他人所指出的那样,在null引用上调用扩展方法会导致this参数为null,并且不会发生任何其他特殊情况 . 这提出了使用扩展方法编写保护子句的想法 .
您可以阅读本文的示例:How to Reduce Cyclomatic Complexity: Guard Clause短版本是这样的:
这是可以在null引用上调用的字符串类扩展方法:
调用工作正常,因为运行时将成功调用null引用上的扩展方法 . 然后你可以使用这个扩展方法来实现guard子句而不会出现凌乱的语法:
extensionmethod是静态的,所以如果你不对这个MyObject做任何事情它应该不是问题,快速测试应该验证它:)
当您希望自己具有可读性和垂直性时,几乎没有什么黄金法则 .
在你的情况下 - DesignByContract被破坏了...你将在null实例上执行一些逻辑 .