Why is my DbNull not single when I deserialize it using XmlSerialiser?

I always assumed that DbNull.value is a single. And so you can do things like this:

VB.NET:

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

FROM#:

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

But lately, I have serialized an instance of DbNull using XmlSerialiser and all of a sudden it was not superfluous. Type comparison operations (like C # (obj - DBNull)) work fine though.

Code follows:

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

Why is this so? And how is this going? And can this happen to any other static fields?

PS: I know that the VB code sample performs a comparative comparison, and C # calls Object.Equals. Both have the same behavior with DBNull. I usually work with VB.

+6
c # dbnull singleton xml-serialization
source share
2 answers

Although DBNull.Value is static readonly and exists only as a single instance ... upon de-serialization, the serialization code will create a new instance of the DBNull class from the "data" into the stream. Since DBNull.Value is just an instance of DBNull , there is no way to serialize to find out that it is a "special" instance.

Note:
For the same reason, if you create your own class with an instance of "singleton" that you serialize and then de-serialize, you will get exactly the same behavior. Although the deserialized instance will be indistinguishable from the original instance, it will not be the same instance.

+7
source share

Your C # code is not equal to calling the .Equals method. Without testing it, I'm really sure if you replaced

 someObject == DbNull.Value 

from

 DbNull.Value.Equals(someObject) 

this will give you the expected result. For some internal elements of the equality operator and the Equals method, consider: Eric Lippers post on this subject

+1
source share

All Articles