2014-07-19 4 views
0

나는 내 자신의 시리얼 라이저를 작성하려고한다. 그러나이 serializer는 속성 만 serialize합니다. 필드 직렬화하는 방법?필드를 직렬화하는 방법은 무엇입니까?

namespace MySerializer 
{ 
class MySerializer 
{ 
    private Type targetType; 
    public MySerializer(Type targetType) 
    { 
     this.targetType = targetType; 
     if (!targetType.IsDefined(typeof(DataContractAttribute), false)) 
      throw new Exception("No soup for you"); 
    } 

    public void WriteObject(Stream stream, Object graph) 
    { 
     IEnumerable<PropertyInfo> serializbleProperties = 
      targetType.GetProperties().Where(p => p.IsDefined(typeof (DataMemberAttribute), false)); 
     var writer = new StreamWriter(stream); 
     writer.WriteLine("<" + targetType.Name + ">"); 
     foreach (PropertyInfo propInfo in serializbleProperties) 
      writer.Write("\t<" + propInfo.Name + ">" + propInfo.GetValue(graph, null) + 
         "</" + propInfo.Name + ">"); 
     writer.WriteLine("</" + targetType.Name + ">"); 
     writer.Flush(); 


    } 

    } 
} 

[DataContract] 
class Person 
{ 
    [DataMember] 
    public string _family; 
    [DataMember] 
    public string FirstName { get; set; } 
    [DataMember] 
    public string LastName { get; set; } 
    [DataMember] 
    public int Age { get; set; } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Person name = new Person 
     { 
      _family = "big", 
      FirstName = "Vasy", 
      LastName = "Bobrow", 
      Age = 20 
     }; 
     MySerializer serializer = new MySerializer(name.GetType()); 
     MemoryStream someRam = new MemoryStream(); 
     serializer.WriteObject(someRam, name); 
     someRam.Seek(0, SeekOrigin.Begin); 
     Console.WriteLine(XElement.Parse(
      Encoding.ASCII.GetString(someRam.GetBuffer()).Replace("\0", ""))); 
    } 
} 

내가 FieldsInfo 대신 PropetryInfo를 사용할 수있는 필드를 직렬화 또는 다른 방법이 : 나는이 수업은 다음과 같습니다?

+1

우선, 왜 자신의 시리얼 라이저를 쓰고 있습니까? 호기심에서 벗어나거나 다른 목적이 있습니까? – ppetrov

+0

Type.GetFields에 대해 뭔가를 MSDN 확인하십시오. –

+0

내가 궁금해서 제 serializer를 쓰고 있습니다. 나는 다른 목적이 없다. 필드의 직렬화 프로젝트를 추가하는 방법을 알고 싶습니다. – Vlad

답변

3

이 질문은 실제로 직렬화에 관한 것이 아니라 반사를 수행하는 방법에 관한 것입니다. 필드와 속성을 모두 반환하려면 GetMembers 메서드를 사용해야하며 속성 및 필드를 찾고 있다고 지정하십시오. 당신이 ">" +을 할 때 모두 당신과 나의 WriteObject 방법은 .ToString() 값에 의존 오버라이드 (override) 할 수이 당신의 writeObject 메소드는 매우 유용 할 것입니다 의심하지만

public void WriteObject(Stream stream, Object graph) 
{ 
    IEnumerable<MemberInfo> serializbleMembers = 
     targetType.GetMembers(BindingFlags.GetField | BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) 
        .Where(p => p.IsDefined(typeof (DataMemberAttribute), false)); 
    var writer = new StreamWriter(stream); 
    writer.WriteLine("<" + targetType.Name + ">"); 
    foreach (MemberInfo memberInfo in serializbleMembers) 
    { 
     writer.Write("\t<" + memberInfo.Name + ">"); 
     var fieldInfo = memberInfo as FieldInfo; 
     if(fieldInfo != null) 
     { 
      writer.Write(fieldInfo .GetValue(graph, null).ToString()); 
     } 

     var propInfo= memberInfo as PropertyInfo; 
     if(propInfo != null) 
     { 
      writer.Write(propInfo.GetValue(graph, null).ToString()); 
     } 

     writer.Write("</" + memberInfo.Name + ">"); 
    } 
    writer.WriteLine("</" + targetType.Name + ">"); 
    writer.Flush(); 


} 

는 (당신은 오른쪽에 무엇이든 암시 .ToString()있다 +에는 .ToString()이 있습니다. 예를 들어, 당신은 .ToString()은 무시했다되지 않은 모든 클래스는 단지 .GetType().Name를 출력하기 때문에 당신이 당신의 출력으로

<Example> 
    <ExampleArray>System.Int32[]</ExampleArray > 
</Example> 

을 얻을 것

[DataContract] 
class Example 
{ 
    public Example() 
    { 
     ExampleArray = new int[] {1, 2}; 
    } 

    [DataMember] 
    int[] ExampleArray {get; set;} 
} 

처럼 뭔가에 클래스를 사용했습니다.

관련 문제