为字符串添加null时为什么没有异常?

时间:2010-07-22 19:15:16

标签: c# string-concatenation

为什么不抛出异常不理解,obj为null

object obj = null;
Console.WriteLine("Hello World " + obj);

5 个答案:

答案 0 :(得分:21)

这将编译为

Console.WriteLine(String.Concat("Hello World ", obj));

String.Concat method会忽略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; 
    }

答案 1 :(得分:3)

null参数传递给方法不一定会抛出异常;这取决于方法的实现(在这种情况下,您可能会看到ArgumentNullException)。

尝试访问null对象的成员 * ** 始终会抛出NullReferenceException,保证***。

因此...

可能会或可能不会抛出异常

object obj = null;
SomeMethod(obj); // passing as parameter

肯定会抛出异常

object obj = null;
int hashCode = obj.GetHashCode(); // calling instance method

对于相关代码,您传递给Console.WriteLine的参数实际上是对string.Concat的编译调用的结果,它允许null值传递为参数并基本上忽略它们 - 如SLaks already pointed out


*扩展方法是另一回事;它们可以在“null”参数上调用;但由于这些只表现出像实例方法一样的幻觉,因此该规则不适用于它们。实际上,扩展方法毕竟只是静态方法。如果您在null值上打一个“on”,则表示您实际上已将null作为参数传递。

**此处我没有将Nullable<T>值包含在HasValue == false中;虽然在很多情况下这些可能会被方便地视为null,但这仅仅是为了语法上的便利:它们不再是null,而是null的任何其他值类型。

***我在这里谈论C#。正如SLaks在评论中指出的那样,这不是CLI本身的规则。但是,C#中的所有实例方法调用都编译为IL中的callvirt指令,如果实例为null抛出异常。

答案 2 :(得分:1)

因为那会很烦人。对于大多数pruposes,空字符串和空字符串之间没有语义差异。

答案 3 :(得分:0)

如果您在实际应用程序中遇到此问题,则可以在显示文本之前始终检查null。然后,您可以显示替代文本,或者不显示任何内容。

答案 4 :(得分:0)

因为他们实现了String.IsNullOrEmpty并留给我们来弄清楚如何使用它。