为字符串添加null时为什么没有exception?
为什么不抛出exception不理解,obj为null
object obj = null; Console.WriteLine("Hello World " + obj);
这编译成
Console.WriteLine(String.Concat("Hello World ", obj));
String.Concat
方法忽略null
参数。
它的定义如下:(来自.Net参考源)
public static String Concat(Object arg0, Object arg1) { if (arg0==null) { arg0 = String.Empty; } if (arg1==null) { arg1 = String.Empty; } return Concat(arg0.ToString(), arg1.ToString()); }
我不知道为什么它不会简单地返回arg1.ToString()
如果arg0==null
。
String.Concat(string, string)
方法定义如下:
public static String Concat(String str0, String str1) { if (IsNullOrEmpty(str0)) { if (IsNullOrEmpty(str1)) { return String.Empty; } return str1; } if (IsNullOrEmpty(str1)) { return str0; } int str0Length = str0.Length; String result = FastAllocateString(str0Length + str1.Length); FillStringChecked(result, 0, str0); FillStringChecked(result, str0Length, str1); return result; }
将null
参数传递给方法不一定会抛出exception; 这取决于方法的实现(在这种情况下,您可能会看到ArgumentNullException
)。
试图访问null
对象的成员 * **将始终抛出NullReferenceException
,保证***。
所以…
可能会或可能不会抛出exception
object obj = null; SomeMethod(obj); // passing as parameter
肯定会抛出exception
object obj = null; int hashCode = obj.GetHashCode(); // calling instance method
在有问题的代码的情况下,传递给Console.WriteLine
的参数实际上是对string.Concat
的编译调用的结果,它允许将null
值作为参数传递并基本上忽略它们 – 正如SLaks已经指出的那样出去
*推广方法是另一回事; 它们可以在“null”参数上调用; 但由于这些只表现出像实例方法一样的幻觉 ,因此这条规则并不适用于它们。 实际上,扩展方法毕竟只是静态方法。 如果您将一个“on”称为null
值,则实际上将null
作为参数传递。
**这里我没有包含Nullable
值和HasValue == false
; 虽然在许多情况下这些可能很方便地被视为null
,但这仅仅是为了语法上的方便:它们不会比任何其他值类型都为null
。
***我在这里谈论C#。 正如SLaks在评论中指出的那样,这不是CLI本身的规则。 但是C#中的所有实例方法调用都被编译为IL中的callvirt
指令,如果实例为null
, 则会抛出exception。
因为那会很烦人。 对于大多数pruposes,空字符串和空字符串之间没有语义差异。
如果您遇到实际应用程序中可能出现此问题的问题,则可以在显示文本之前始终检查null。 然后,您可以显示替代文本,或者不显示任何内容。
因为他们实现了String.IsNullOrEmpty并留给我们来弄清楚如何使用它。