2009-06-04 12 views
6

मैंने हमेशा यह माना है कि DbNull.value एक सिंगलटन था। और इस तरह आप इस तरह की बातें कर सकता है:जब मैं XmlSerialiser का उपयोग कर इसे deserialise करता हूं तो मेरा डीबीएनएल एक सिंगलटन क्यों नहीं है?

VB.NET:

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

सी #:

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

लेकिन हाल ही में, मैं XmlSerialiser का उपयोग कर एक 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; 

} 

क्यों यह मामला है? और यह कैसे होता है? और क्या यह संभवतः किसी अन्य स्थिर क्षेत्रों के साथ हो सकता है?

पीएस: मुझे पता है कि वीबी कोड नमूना संदर्भ तुलना कर रहा है और सी # ऑब्जेक्ट को कॉल कर रहा है। एक्वाल्स। दोनों के पास डीबीएनयूएल के साथ एक ही व्यवहार है। मैं आमतौर पर वीबी के साथ काम करता हूं।

+0

मैं कुछ घंटों के लिए काफी समानता से गड़बड़ कर रहा हूं ... मैंने आईएस डीबीएनयूएल को भी आजमाने की कोशिश नहीं की। – Feign

उत्तर

7

हालांकि DBNull.Value एक static readonly है और केवल एक उदाहरण के रूप में मौजूद ... जब आप को डी-serialize, क्रमबद्धता कोड धारा में 'डेटा' से वर्ग DBNull का एक नया उदाहरण बनाने की जाएगी। चूंकि DBNull.Value बस DBNull उदाहरण है, इसलिए सीरियलाइजेशन को यह जानने का कोई तरीका नहीं है कि यह एक 'विशेष' उदाहरण है।

नोट:
उसी कारण से, अगर आप एक 'सिंगलटन' उदाहरण है कि आप को क्रमानुसार और उसके बाद डी-serialize आप बिल्कुल वैसा ही व्यवहार हो जाएगा के साथ अपने स्वयं वर्ग बनाते हैं। यद्यपि deserialized उदाहरण मूल उदाहरण से अलग नहीं होगा, वे एक ही उदाहरण नहीं होगा।

+0

बह! जादू क्रमबद्धता कोड पर एक पॉक्स। हालांकि उत्तर के लिए ता। – ligos

+0

सभी जादू सफेद नहीं हो सकते हैं ...;) – jerryjvl

1

आपका सी # कोड इक्विटी विधि को कॉल करने के बराबर नहीं है। साथ बाहर यह वास्तव में यकीन है कि परीक्षण किया होने इम अगर आप

DbNull.Value.Equals(someObject) 

साथ

someObject == DbNull.Value 

प्रतिस्थापित यह आप अपेक्षित परिणाम देना होगा। समानता ऑपरेटर और बराबर विधि पर कुछ अंतर्दृष्टि के लिए एक नज़र डालें: Eric Lipperts blog post on that subject

+0

मैंने पहले बराबर() के संयोजन का प्रयास नहीं किया, लेकिन यह काम नहीं करता है। ऑब्जेक्ट। रीफ एक्वाल्स (ओबीजे, डीबीएनयूएल.वैल्यू), ऑब्जेक्ट। एक्वाल्स (ओबीजे, डीबीएनयूएल.वेल्यू), ओबीजे == डीबीएनयूएल.वेल्यू, और डीबीएनयूएल। वैल्यू। एक्वाल्स (ओबीजे) सभी deserialisation के बाद झूठी वापसी। – ligos