لماذا ليست بلدي dbnull singleton عندما أريدها باستخدام xmlserialiser؟

StackOverflow https://stackoverflow.com/questions/948675

سؤال

لقد افترضت دائما أن DBNull.Value كان سينطون. وبالتالي يمكنك القيام بأشياء مثل هذا:

vb.net:

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

C #:

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

ولكن في الآونة الأخيرة، أقوم بتسلسل مثيل DBNull باستخدام XMLSerialiser وفجأة لم يكن أكثر من Singleton. اكتب عمليات المقارنة (مثل 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;

}

لماذا هذا هو الحال؟ وكيف يحدث ذلك؟ ويمكن أن يحدث مع أي حقول ثابتة أخرى؟

ملاحظة: أنا أدرك عينة رمز VB تقوم بمقارنة مرجعية و C # هي كائن الاتصال. كلاهما لديه نفس السلوك مع dbnull. أنا عادة العمل مع vb.

هل كانت مفيدة؟

المحلول

برغم من DBNull.Value هو static readonly ووفر فقط كحل واحد ... عند إزالة التسلسل، سيقوم رمز التسلسل بإنشاء مثيل جديد من الفصل DBNull من "البيانات" في الدفق. منذ DBNull.Value هو ببساطة أ DBNull على سبيل المثال، لا توجد وسيلة للاستسلالية لمعرفة أنها مثيل "خاص".

ملاحظة:
لنفس السبب، إذا قمت بإنشاء فصلك الخاص من خلال مثيل "Singleton" تسلسل، فستتحصل على تسلسلك نفس السلوك بالضبط. على الرغم من أن المثيل الهجومي لا يمكن تمييزه عن المثيل الأصلي، فلن يكونوا كذلك نفس المثال.

نصائح أخرى

رمز C # الخاص بك غير متساوي في استدعاء طريقة. المساواة. مع الخروج بعد اختبارها في الواقع بالتأكيد إذا استبدلت

someObject == DbNull.Value

مع

DbNull.Value.Equals(someObject) 

سوف يمنحك النتيجة المتوقعة. بالنسبة لبعض المستخدمين حول مشغل المساواة والطريقة المساواة نلقي نظرة على:خط الكتب إريك بلوق على هذا الموضوع

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top