2009-06-04 5 views
6

나는 항상 DbNull.value가 싱글 톤이라고 가정했다. 따라서이 같은 일을 할 수있는 :XmlSerialiser를 사용하여 deserialise 할 때 내 DbNull이 싱글 톤이 아닌 이유는 무엇입니까?

VB.NET :

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

C 번호 :

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

그러나 최근에, 나는 XmlSerialiser를 사용하여 DBNULL 인스턴스를 직렬화하고 갑자기 아니었다 더 이상 싱글 톤. 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#이 Object.Equals를 호출하고 있음을 알고 있습니다. 둘 다 DBNull과 동일한 동작을합니다. 나는 보통 VB에서 일한다. DBNull.Value 비록

+0

저는 몇 시간 동안 비슷한 점이 있습니다. 나는 IS DBNull을 시도해 보지도 않았습니다. – Feign

답변

7

static readonly입니다 만 당신이 일련 화를 해제 할 때, 직렬화 코드는 스트림의 '데이터'에서 클래스 DBNull의 새로운 인스턴스를 생성하는 것입니다 ... 단일 인스턴스로 존재한다. DBNull.Value은 단순히 DBNull 인스턴스이기 때문에 직렬화가 해당 인스턴스가 '특별한'인스턴스라는 것을 알 수있는 방법이 없습니다.

참고 : 당신은 당신이 직렬화하고 역 직렬화 정확히 동일한 동작을 얻을 것이다 '싱글'인스턴스와 자신의 클래스를 만들 경우 같은 이유로
. 직렬화 해제 된 인스턴스는 원래 인스턴스와 구별 할 수 없지만 같은 인스턴스이 아닙니다.

+0

Bah! 마법 직렬화 코드에 대한 두드러기. 대답에 대한 Ta. – ligos

+0

모든 마술이 흰색이 될 수있는 것은 아닙니다 ...;) – jerryjvl

1

C# 코드가 .Equals 메서드를 호출하는 것과 다릅니다. 당신이

DbNull.Value.Equals(someObject) 

someObject == DbNull.Value 

교체되어 있는지 실제로 확신 그것에게 임 테스트를 갖는 그것은 당신에게 예상 된 결과를 줄 것이다. 평등 연산자와 Equals 메서드의 내부에 대해서는 다음을 살펴보십시오. Eric Lipperts blog post on that subject

+0

전에 Equals() 조합을 시도하지는 않았지만 작동하지 않습니다. deserialisation 후에 Object.RefEquals (obj, DbNull.Value), Object.Equals (obj, DbNull.Value), obj == DBNull.Value 및 DbNull.Value.Equals (obj)는 모두 false를 반환합니다. – ligos

관련 문제