`
RednaxelaFX
  • 浏览: 3015434 次
  • 性别: Icon_minigender_1
  • 来自: 海外
社区版块
存档分类
最新评论

Nullable的诡异之处……

    博客分类:
  • C#
阅读更多
原来Nullable type是null的时候,以它作为被调用对象是不会得到NullReferenceException的。以前都没发现,得小心点才行……

引用Steve Wellens在CodeProject上发表的C# Nullable Types…Subtlety
 int Test1 = 0;  // standard value type
 int? Test2 = null; // nullable value type  
 Object Test3 = null; // reference type

 Response.Write("Test1: " + Test1.ToString() + "<br />");
 Response.Write("Test2: " + Test2.ToString() + "<br />");
 //Response.Write("Test3: " + Test3.ToString() + "<br />");

 // Output:
 //
 // Test1: 0 // correct
 // Test2: // no exception, what? but it's null!
 //
 // If Test3 is allowed to run, we get:
 // "Object reference not set to an instance of an object."

(他这段代码是在ASP.NET里测试的,所以是用Response.Write())

更新:
参照下面的回复:Nullable<T>是值类型,自身不会为null。使执行int? Test2 = null;之后,Test2指向的是一个代表null的Nullable<int>的实例,所以后面自然不会有异常。
分享到:
评论
6 楼 kangyiwei 2010-06-11  
ToString被重写了

public override string ToString()
{
    if (!this.HasValue)
    {
        return "";
    }
    return this.value.ToString();
}
5 楼 RednaxelaFX 2009-06-04  
beyondest 写道
首先看第一句。Nullable<T>是值类型,Test2不可能为null。

嗯,说得没错,后来我也知道了,不过这帖一直忘了更新。多谢提醒 ^ ^
4 楼 beyondest 2009-06-03  
这个没有什么诡异的。

int? Test2 = null;
Test2.ToString();

首先看第一句。Nullabla<T>是值类型,Test2不可能为null。

实际上int? Test2 = null执行后,Test2根本不是null,而是栈上一个Nullabla<System.Int32>的实例。所以调用Test2.ToString()不会抛NullReferenceException。

当前Test2的hasValue被初始化为false。如果这时调用Test2的Value,会抛异常。
3 楼 garfeildma 2009-04-03  
引用
Tests? 是指string类型的变量赋值为null然后输出么?
要注意单参数的Console.WriteLine()本身是不介意参数是null的,


写错了,Test3.

又试了一下的确这样
                
                int Test1 = 0;  // standard value type   
                int? Test2 = null; // nullable value type     
                Object Test3 = null; // reference type   

                Console.WriteLine(Test1);
                Console.WriteLine(Test2.ToString());
                Console.WriteLine(Test3.ToString());


用Reflector看到是这样的
            int num = 0;
            int? nullable = null;
            object obj2 = null;
            Console.WriteLine(num);
            Console.WriteLine(nullable.ToString());
            Console.WriteLine(obj2.ToString());
2 楼 RednaxelaFX 2009-04-03  
garfeildma 写道

我试了一下Console.WriteLine(Tests)也不会报错

Tests? 是指string类型的变量赋值为null然后输出么?
要注意单参数的Console.WriteLine()本身是不介意参数是null的,
class Class1 {    
    static void Main(string[] args) {
      string s = null;
      System.Console.WriteLine(s);
    }
}

这个没问题。问题是在.ToString()那里。被调用的对象如果是null的话,这里就会抛NullReferenceException,
class Class1 {    
    static void Main(string[] args) {
      string s = null;
      System.Console.WriteLine(s.ToString());
    }
}

这样就有问题了。
但把这个例子里的string换成int?之后又没问题了,所以说诡异……本来Nullable应该跟其它引用类型保持一致的语义才对。
1 楼 garfeildma 2009-04-03  
我试了一下Console.WriteLine(Tests)也不会报错

相关推荐

Global site tag (gtag.js) - Google Analytics