2009-06-04 8 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で動作します。 DBNull.Valueものの

+0

を...私もISはDBNullをしようとするとは思いませんでした。 – Feign

答えて

7

static readonlyであり、唯一のあなたは、シリアル化を解除したときに、シリアル化コードは、ストリーム内の「データ」から、クラスDBNullの新しいインスタンスを作成することでしょう...単一インスタンスとして存在します。 DBNull.Valueは単にDBNullインスタンスなので、それが「特別な」インスタンスであることをシリアル化する方法はありません。あなたがシリアライズして、あなたは正確に同じ動作を取得するデシリアライズすることを「シングルトン」のインスタンスを使用して独自のクラスを作る場合にも、同じ理由で
、:

NOTE。デシリアライズされたインスタンスは元のインスタンスと区別できませんが、の同じインスタンスにはなりません。

+0

Bah!魔法のシリアライズコードのポックス。しかし、答えのためのTa。 – ligos

+0

すべての魔法が白くなるわけではありません...;) – jerryjvl

1

あなたのc#コードは.Equalsメソッドの呼び出しと同じではありません。アウトを使用すると、

DbNull.Value.Equals(someObject) 

someObject == DbNull.Value 

を置換した場合、実際にかなり確信してイムそれをテストしたそれはあなたの期待される結果を与えるだろう。等価演算子とequalsメソッドにいくつかの内部が見取るために:私は今、数時間のためにかなり似たようないじりてきた Eric Lipperts blog post on that subject

+0

私はその前にEquals()を試しませんでしたが、うまくいきません。 obj == DBNull.Value、およびDbNull.Value.Equals(obj)はすべて、デシリアライズ後にfalseを返します。Object.RefEquals(obj、DbNull.Value)、Object.Equals(obj、DbNull.Value) – ligos

関連する問題