2012-05-22 2 views
8

XMLSerializer를 사용하여이 클래스를 파일에 저장합니다. 이 클래스는 다음과 같이 문자열과 열거 형을가집니다.XmlSerializer : 더 이상 존재하지 않는 enum 값을 역 직렬화하는 방법

public class IOPoint 
{ 
    string Name {get; set;} 
    TypeEnum {get; set;} 
} 


public enum TypeEnum 
{ 
    Temperature, 
    Pressure, 
    Humidity, 
} 

직렬화하면 다음과 같이 표시됩니다.

<IOPoint> 
    <Name>Relative Humidity</Name> 
    <TypeEnum>Humidity</TypeEnum> 
</IOPoint> 

나는 직렬화 및 여러 버전의 문제없이이 객체를 직렬화 복원했습니다. 나는 더 이상 습도를지지하고 싶지 않아 열거에서 제거했습니다. 그러나 TypeEnum 필드의 값인 Humidity가 TypeEnum에 유효한 값이 아니므로 XML에서 deserialize 할 때 예외가 발생합니다. 이것은 의미가 있지만 이것을 처리하는 방법은 무엇입니까?

내가하고 싶은 것은이 오류를 그냥 무시하는 것입니다. 값을 null로 두십시오. OnUnknownElement XmlDeserilizationEvent 클래스를 구현하려고 시도했습니다. 불행히도이 오류는 발생하지 않습니다.

이 오류를 잡아 내고 무시하는 방법에 대한 아이디어가 있습니다. (비 직렬화가 완료된 후 정리할 수 있습니다).

미치

+0

해결책을 찾았다면 알고 싶습니다. 나는 클라이언트가 알지 못하는 새로운 enum 플래그 값을 포함하는 서버 측과 관련된 관련 문제를 가지고있다. 그래서 정말 한 필드의 직렬화를 관리하는 방법을 찾고 싶다. 다음에 나는 int를 사용 하겠지만, 지금은 ... backward compatibility. – avenmore

답변

5

당신은 당신의 라이브러리가 이미 사용 후에는 일반적으로 열거 형 멤버를 제거하는 나쁜 관행 간주

public enum TypeEnum 
{ 
    Temperature, 
    Pressure, 
    [Obsolete] 
    Humidity 
} 
+2

[사용되지 않는] 특성을 사용할 수없는 이유는 열거 형 값을 반복하는 코드에서 일반적으로 사용되기 때문입니다. 따라서 "습도"가 쓸모 없게 표시 되더라도 foreach 루프에서는 여전히 나타납니다. (열거자를 덮어 쓰는 방법이 없다면) – Mitch

+0

변수를 사용하는 곳마다 변수를 null로 만들 수 있습니까? 예 : TypeEnum?val = null; –

4

사용되지 않는 구성원을 표시 할 수 있습니다. 회원을 그 자리에 두지 않고 나중에 사용하지 못하도록 [Obsolete] 속성으로 표시하는 것이 어떻습니까? ObsoleteAttribute(string,bool) 생성자의 두 번째 매개 변수를 true으로 지정하면 표시된 멤버에 액세스하면 컴파일 타임 오류가 발생합니다. typeEnum == (TypeEnum)2을 :

public enum TypeEnum 
{ 
    Temperature, 
    Pressure, 

    [Obsolete("It's always sunny in Philadelphia", true)] 
    Humidity, 
} 

오류 직렬화 값을 검사 할 때, 당신은 기본 값과 비교할 수를 우회합니다.

1

IXmlSerializable을 구현할 수 있습니다. 여기에서 TryParse를 열거 형으로 사용할 수 있습니다.

하지만 Obsolete 속성을 사용하는 다른 포스터에 동의합니다.

+0

다른 해결 방법을 찾을 수없는 경우 IXMLSerializable을 사용하는 사용자 지정 serialization이 유일한 해결책입니다. 필자가이 작업을 수행하는 동안 비 직렬화를 안내하는 데 사용할 수있는 버전 필드도 추가 할 것입니다. ISerializable을 사용할 때 우리는 비슷한 것을합니다. 실제 수업에는 약 15 개의 필드가 있습니다. 한 필드에 대한 디시리얼라이저 코드 만 작성하면 되겠습니까? – Mitch

2
수동 그냥 하나 개의 요소 분석, 주변 노드 이름을 변경하고 XML 직렬화에서 요소를 숨기기 위해 속성을 사용할 수 있습니다

:

public class IOPoint 
{ 
public string Name {get; set;} 

[XmlIgnore] 
public TypeEnum TypeEnum {get; set;} 

[XmlElement("TypeEnum")] 
public string LegacyTypeEnum 
{ 
    get { return this.TypeEnum.ToString(); } 
    set 
    { 
    try 
    { 
    this.TypeEnum = (TypeEnum)Enum.Parse(typeof(TypeEnum),value); 
    } 
    catch(ArgumentException) 
    { 
    // Handle "Humidity" 
    } 
    catch(OverflowException) 
    { 
    } 
    } 
} 
} 

당이 약간의 혼동이있을 나타납니다 코멘트를; Visual Studio 2010 프로젝트로 here is a worked example. 이 방법은 개체의 한 속성 만 수동으로 구문 분석하는 간단한 방법입니다 (여전히 XmlSerializer를 사용하여 XML 구문 분석을 수행함).

+0

enum 값을 열거 형 대신 문자열로 serialize하는 것은 읽어야하는 XML 파일이 아직없는 경우 좋은 생각입니다. 이러한 기존 파일은 요소를 가지고 있으며 TypeEnum 필드의 값을 읽고 그에 따라 작동해야합니다. 이상적인 솔루션은 습도 값을 deserialize하려고 할 때 예외를 잡는 것입니다. 그러나 디시리얼라이저에 넣은 예외 핸들러 중 어느 것도이 오류를 catch하지 않습니다. – Mitch

+0

필자는 그것이 작동하고 작동하는 방법을 보여주기 위해 컴파일 가능한 샘플을 포함 시켰습니다. – user423430

관련 문제