protobuf-net - Decorate class

protobuf-net 要設定類別怎樣被序列化與解序列化有三種方式‧


像是使用 protobuf-net 提供的 Attribute,類別上用 ProtoContractAttribute、Property 上用 ProtoMemberAttribute‧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[ProtoContract] 
class Person {
[ProtoMember(1)]
public int Id {get;set;}
[ProtoMember(2)]
public string Name {get;set:}
[ProtoMember(3)]
public Address Address {get;set;}
}

[ProtoContract]
class Address {
[ProtoMember(1)]
public string Line1 {get;set;}
[ProtoMember(2)]
public string Line2 {get;set;}
}


如果有繼層的類別可以透過 ProtoIncludeAttribute 設定。

1
2
3
4
5
6
7
8
9
10
11
12
13
[ProtoContract] 
[ProtoInclude(10, typeof(Male))]
[ProtoInclude(11, typeof(Female))]
class Person {
[ProtoMember(1)]
public string Name { get; set; }
}

[ProtoContract]
class Male : Person { }

[ProtoContract]
class Female : Person { }


ProtoContractAttribute 這邊還有提供些設定,像是 SkipConstructor 可以讓類別解序列化時不需要有建構子、ImplicitFields 可以設定全部的欄位或是屬性都序列化解序列化。

1
2
3
4
5
6
7
8
9
10
11
12
13
[ProtoContract(SkipConstructor = true, ImplicitFields = ImplicitFields.AllFields)] 
class Person {
public string Name { get; set; }
public Person(string name) {
Name = name;
}

[ProtoAfterDeserialization]
void Validate() {
if (string.IsNullOrEmpty(Name))
throw new Exception("Empty name");
}
}


除了 protobuf-net 提供的 Attribute 外,protobuf-net 也提供 .NET Framework 內建的 DataContractAttribute。

1
2
3
4
5
[DataContract] 
class Person {
[DataMember(Order = 1)]
public string Name { get; set; }
}


如果不想用 Attribute 的方式設定,也可以透過 RuntimeTypeModel 設定。

1
2
3
4
5
6
7
class Person { 
public string Name { get; set; }
}

RuntimeTypeModel.Default
.Add(typeof(Person), false);
.Add(1, "Name");