Frage

Ich habe immer davon ausgegangen, dass DBNull.Value ein Singleton ist. Und so könnte man die Dinge tun, wie folgt:

VB.NET:

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

C #:

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

Aber vor kurzem, ich serialisiert eine DBNULL Instanz der XmlSerialiser mit und es war plötzlich kein Singleton mehr. Typ Vergleichsoperationen (wie C # 's (obj ist DBNull)) arbeiten jedoch OK.

-Code folgt:

[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;

}

Warum ist dies der Fall? Und wie kommt es dazu? Und kann es möglicherweise mit anderen statischen Feldern geschehen?

PS: Ich bin das VB-Codebeispiel bewusst einen Referenz Vergleich tut und c # rufe Object.Equals. Beide haben das gleiche Verhalten mit DBNull. Ich arbeite in der Regel mit VB.

War es hilfreich?

Lösung

Obwohl DBNull.Value ein static readonly ist und existiert nur als eine einzige Instanz ... wenn Sie Deserialisieren, würde der Serialisierungscode eine neue Instanz der Klasse DBNull aus den ‚Daten‘ im Stream erschaffen. Da die DBNull.Value einfach eine DBNull Instanz, gibt es keine Möglichkeit für die Serialisierung zu wissen, dass es eine ‚besondere‘ Instanz ist.

Hinweis:
Aus dem gleichen Grunde, wenn Sie Ihre eigene Klasse mit einer ‚Singleton‘ Instanz, die Sie serialisieren und dann deserialisieren Sie genau das gleiche Verhalten bekommen. Obwohl die entserialisierten Instanz nicht von der ursprünglichen Instanz sein wird, wird sie nicht die gleiche Instanz .

Andere Tipps

Ihre c # -Code nicht gleich dem .Equals Methode aufrufen. Mit heraus, es Im getestet hat eigentlich ziemlich sicher, wenn Sie ersetzt

someObject == DbNull.Value

mit

DbNull.Value.Equals(someObject) 

es würde Ihnen das erwartete Ergebnis. Für einige Innenseite auf dem Gleichheitsoperator und die Equals-Methode zu sehen: Eric Lipperts Blog-Post zu diesem Thema

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top