之前遇到需要在 XML 序列化的過程中忽略值為空值或預設值的欄位, 查了一下才發現不太好找而且做法沒有很直覺.
作法
bool ShouldSerialize{PropertyName}
建立回傳型別為 bool 的方法, 方法名稱必須為 ShouldSerialize 加上屬性名.  
1  | public class M  | 
唯獨屬性 {PropertytName}Specified
建立唯獨屬性, 名稱必須為屬性名加上 Specified, 有幾個細節:
- 不一定要是唯獨屬性, 有 setter 也可以, 但是沒意義, 不要這樣做.
 - Attribute 
System.Xml.Serialization.XmlIgnore不是必要的 (因為唯獨), 但建議要加, 避免有人加了 setter 或其他因素而導致他被序列化, 閱讀時也多一個提示效果. 
1  | public class M  | 
呼叫端與綜合分析
簡單的呼叫端範例.1
2
3
4
5
6
7
8
9
10
11
12public class Program
{
    public static void Main()
    {
        var m = new M();
        m.S = "";
        XmlSerializer xs = new XmlSerializer(typeof(M));
        StringWriter sw = new StringWriter();
        xs.Serialize(sw, m);
        Console.WriteLine(sw.ToString());
    }
}
建議:
- 優先使用
 bool ShouldSerialize{PropertyName}方法, 主要原因是因為他名字比較好記也比較直覺, 另外一個做法比較麻煩.- 將屬性和條件拆開成個獨立的檔案搭配 partial class, 範例如下:
 
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 > // M.cs
> public partial class M
> {
> public string S { get; set; }
> public int N { get; set; }
> }
>
> // M.Ignore.cs
> public partial class M
> {
> public bool ShouldSerializeS()
> {
> return !string.IsNullOrEmpty(S);
> }
> }
>
結論
找到解法的時候其實很驚訝, 因為這種做法維護上其實會有點困擾, 想想如果屬性要改名, 結果還要有意識的刻意找出 ShouldSerialize{PropertyName} 或是 {PropertytName}Specified 來修改, 對於維護其實不太友善, 只是沒有找到其他做法也就先拿來用了.