Question

Je l'ai toujours pensé que DBNull.Value était un singleton. Et ainsi, vous pouvez faire des choses comme ceci:

VB.NET:

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

C #:

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

Mais récemment, je sérialisé une instance DBNull utilisant le XmlSerialiser et tout à coup ce ne fut pas un singleton plus. opérations de comparaison de type (comme C # 's (obj est DBNull)) fonctionnent OK si.

Code suit:

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

}

Pourquoi est-ce le cas? Et comment se fait-il? Et peut-il se produire éventuellement avec d'autres champs statiques?

PS: Je connais l'exemple de code VB fait une comparaison de référence et c # APPELLE Object.Equals. Tous les deux ont le même comportement avec DBNull. Je travaille habituellement avec VB.

Était-ce utile?

La solution

Bien que DBNull.Value est un static readonly et existe seulement comme une seule instance ... lorsque vous désérialiser, le code de sérialisation serait de créer une nouvelle instance de la classe DBNull de la « données » dans le flux. Étant donné que le DBNull.Value est tout simplement une instance DBNull, il est pour la sérialisation aucun moyen de savoir qu'il est une instance « spéciale ».

Remarque: Pour la même raison, si vous faites votre propre classe avec une instance « singleton » que vous sérialiser et désérialiser vous obtiendrez exactement le même comportement. Bien que l'instance désérialisé sera impossible à distinguer de l'instance d'origine, ils ne seront pas la même instance .

Autres conseils

Votre code C # ne correspond pas à appeler la méthode Equals. Avec en ayant testé Im en fait assez sûr si vous avez remplacé

someObject == DbNull.Value

avec

DbNull.Value.Equals(someObject) 

il vous donner le résultat escompté. Pour certains sur l'opérateur intérieur de l'égalité et la méthode Equals jeter un oeil à: Eric blog Lipperts sur ce sujet

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top