2010-01-26 3 views
5

일부 컬렉션이 포함 된 클래스가 있습니다. 컬렉션을 비워 둘 필요없이 IXmlSerializable을 구현하지 않고이 클래스의 인스턴스를 XML로 serialize하고자합니다. 빈 요소를 생성하는지 또는 요소를 전혀 작성하지 않든 상관 없습니다. 각 컬렉션 기반 속성에 대한 컬렉션을 초기화하지 않고도 작동합니다..NET XML serialization 및 Null 컬렉션

속성을 장식 할 수있는 모든 XML 특성을 살펴본 결과이 기능을 사용하지 못했습니다. 이것은 요소를 가질 수도 있고 전혀 가질 수도없는 간단한 일처럼 보입니다. 그런 다음 deserialize 될 때 그것은 null로 남겨 두거나 그 기간을 무시합니다.

다음은이 문제를 해결하는 데 사용할 간단한 버전의 클래스입니다. 이 값과 기본값을 사용하면 컬렉션이 null로 인해 "객체 참조가 객체의 인스턴스로 설정되지 않았습니다."예외가 발생합니다. 에 대한

public class MyClass 
{ 
    public string Name { get; set; } 
    public bool IsAlive { get; set; } 
    public List<Car> Cars { get; set; } 
    public List<Home> Homes { get; set; } 
    public List<Pet> Pets { get; set; } 

    public void ToXmlFile(string fileName) 
    { 
     XmlSerializer serializer = new XmlSerializer(typeof(MyClass)); 
     TextWriter writer = new StreamWriter(fileName); 
     serializer.Serialize(writer, this); 
     writer.Close(); 
    } 
} 

편집 감사는 문제가 제대로 널을 처리하지 않았다 내를 GetHashCode 방법이었다 밝혀, 사람을 도움이됩니다. 일단 내가 고쳤다면 좋았어. 나는 올바른 것으로 대답 할 첫 번째 것을 표시했다. Red Herring을 유감스럽게 생각합니다.

+0

그리고 무엇이 문제입니까? 그것은 작동해야합니다 (적어도 직렬화 및 비 직렬화). 당신이 좋아하지 않는 행동은 무엇입니까? –

+0

귀하가 주장하는 예외를 재현 할 수 없습니다. 내가 준 MyClass의 인스턴스를 serialize하고 deserialize 할 수있었습니다. 어쩌면 다른 일이있을 수 있습니까? –

+0

@Brian 네, 뭔가 다른 일이 일어나고있었습니다. 모든 빠른 도움과 XML 코드 자체가 아닌 것을 보여주는 덕분입니다. :) –

답변

5

클래스를 XML로 직렬화하기 위해 컬렉션을 초기화 할 필요가 없습니다. 다음은 간단한 프로그램을 보여이다 : 즉

<?xml version="1.0"?> 
<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Name>Test</Name> 
    <IsAlive>true</IsAlive> 
</MyClass> 

, null 수집 속성이 다른 null 속성과 동일한 방식으로 작동합니다 - 그들은하지 않습니다

class Program 
{ 
    static void Main(string[] args) 
    { 
     MyClass c = new MyClass() { Name = "Test", IsAlive = true }; 
     XmlSerializer serializer = new XmlSerializer(typeof(MyClass)); 
     using (MemoryStream ms = new MemoryStream()) 
     { 
      serializer.Serialize(ms, c); 
      Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray())); 
     } 
     Console.ReadLine(); 
    } 
} 

이 다음과 같은 출력을 인쇄합니다 (당신이 디폴트 값을 변경하지 않는다면, 나는 그렇지 않다).

+0

질문을 업데이트했습니다.이 작업을 수행 할 때 "개체 참조가 개체의 인스턴스로 설정되지 않았습니다"예외가 발생합니다. StreamWriter를 사용하는 파일에이 작업을 수행하고 클래스 자체에서 ToXmlFile 메서드를 사용하여 "this"키워드를 사용하여 직렬화 할 개체를 참조합니다. 일반 목록에 정의 된 클래스는 기본 요소 또는 열거 형을 사용하여 단순합니다. 당신이 말하는 것은 그것이 어떻게 작동 할 것이라고 기대하지만, 그렇지 않습니다. 직렬화에 사용되는 코드로 클래스를 업데이트 할 것이다. –

+0

감사합니다. 문제는 브라이언이 질문에 대한 자신의 의견에서 벗어난 다른 곳에서 발생했습니다. –

0

extraTypes 매개 변수로 직렬화 할 때 자동차, 집 및 애완 동물 유형 만 보내면 문제없이 문제없이 직렬화 할 수 있습니다.

0

(de) 직렬화 중에 예외가 언급됩니다. 당신이 가지고있는 것은 OK (적어도 당신이 질문을 어떻게 정의하는지에 따라)해야합니다.당신이 실제로 가지고 있는지 궁금해 :

public class MyClass 
{ 
    public string Name { get; set; } 
    public bool IsAlive { get; set; } 
    public List<Car> Cars { get; private set; } 
    public List<Home> Homes { get; private set; } 
    public List<Pet> Pets { get; private set; } 
} 

음 (공공 세터을 원하지하는 드문 일이 아니다), XmlSerializer 이것에 대해 까다로운이다; 공공 세터가 필요하거나 (최근에 누군가 지적한 바와 같이) 세터; 예를 들면 :

public class MyClass 
{ 
    public string Name { get; set; } 
    public bool IsAlive { get; set; } 
    private readonly List<Car> cars = new List<Car>(); 
    public List<Car> Cars { get { return cars; } } 
    private readonly List<Home> homes = new List<Home>(); 
    public List<Home> Homes { get { return homes; } } 
    private readonly List<Pet> pets = new List<Pet>(); 
    public List<Pet> Pets { get { return pets; } } 
} 
0

을 나는 현재의 방법과 반대로 당신이 안전한 방식으로 오류를 처리 할 수 ​​있도록 해주는 부울에 XMLSerialisation 메서드의 반환 형식을 설정하는 생각 :

public bool ToXmlFile(string fileName) 
{ 
    if(fileName != "") 
    { 
     XmlSerializer serializer = new XmlSerializer(typeof(MyClass)); 
     TextWriter writer = new StreamWriter(fileName); 
     serializer.Serialize(writer, this); 
     writer.Close(); 
     return true; 
    } 
    return false; 
} 

어떤

if(ToXMLFile) 
{ 
    MessageBox.Show("Save Succesful"); 
} 
else 
(
    MessageBox.Show("Save unsuccesful"); 
) 

이것은 아주 조잡한 예제 일 뿐이지 만, 저는 loa 데이터를 저장하거나 저장하고 잘 작동하며 최종 사용자에게 좋은 시각적 표시기입니다.