2009-06-04 20 views
6

我一直認爲DbNull.value是一個單身人士。這樣的話你可以做這樣的事情:當我使用XmlSerialiser進行反序列化時,爲什麼不是我的DbNull單例?

VB.NET:

If someObject Is DbNull.Value Then 
    ... 
End if 

C#:

If (someObject == DbNull.Value) 
{ 
    ... 
} 

但最近,我連載使用XmlSerialiser一個實例,則爲DBNull,突然它不是再單身一人。類型比較操作(如C#的(obj是DBNull))工作確定。

代碼如下:

[Serializable, System.Xml.Serialization.XmlInclude(typeof(DBNull))] 
public class SerialiseMe 
{ 
    public SerialiseMe() { } 

    public SerialiseMe(object value) 
    { 
     this.ICanBeDbNull = value; 
    } 
    public Object ICanBeDbNull { get; set; } 
} 

public void Foo() 
{ 
    var serialiseDbNull = new SerialiseMe(DBNull.Value); 
    var serialiser = new System.Xml.Serialization.XmlSerializer(typeof(SerialiseMe)); 
    var ms = new System.IO.MemoryStream(); 
    serialiser.Serialize(ms, serialiseDbNull); 
    ms.Seek(0, System.IO.SeekOrigin.Begin); 
    var deSerialisedDbNull = (SerialiseMe)serialiser.Deserialize(ms); 

    // Is false, WTF! 
    var equalsDbNullDeserialised = deSerialisedDbNull.ICanBeDbNull == DBNull.Value; 
    // Is false, WTF! 
    var refEqualsDbNullDeserialised = object.ReferenceEquals(deSerialisedDbNull.ICanBeDbNull, DBNull.Value); 
    // Is true. 
    var convertIsDbNullDeserialised = Convert.IsDBNull(deSerialisedDbNull.ICanBeDbNull); 
    // Is true. 
    var isIsDbNullDeserialised = deSerialisedDbNull.ICanBeDbNull is DBNull; 

} 

爲什麼會出現這種情況?它是如何發生的?它可能會發生與其他任何靜態字段?

PS:我知道VB代碼示例正在做參考比較,而c#正在調用Object.Equals。兩者與DBNull具有相同的行爲。我通常使用VB。

+0

我一直在搞相當幾個小時的東西......我甚至沒有想過要試試DBNull。 – Feign 2015-01-13 16:39:29

回答

7

雖然DBNull.Valuestatic readonly,現在僅作爲一個實例...當你反序列化,序列化代碼將從流中的「數據」來創建類DBNull的新實例。由於DBNull.Value只是一個DBNull實例,所以序列化無法知道它是一個「特殊」實例。

注:
出於同樣的原因,如果你讓你自己的類與序列化,然後反序列化,你會得到完全相同的行爲「單身」實例。雖然反序列化的實例與原始實例無法區分,但它們不會是與實例相同。

+0

Bah!關於魔法序列化代碼的痘痘。 Ta雖然答案。 – ligos 2009-06-04 07:02:15

+0

不是所有的魔法都可以是白色的...;) – jerryjvl 2009-06-04 09:21:54

1

您的c#代碼不等於調用.Equals方法。隨着出已經測試了它我其實非常肯定,如果你取代

someObject == DbNull.Value 

DbNull.Value.Equals(someObject) 

它會給你預期的結果。對於平等運算符和Equals方法的一些內部看看: Eric Lipperts blog post on that subject