次のコードがあります。
[Serializable]
public class CustomClass
{
public CustomClass()
{
this.Init();
}
public void Init()
{
foreach (PropertyInfo p in this.GetType().GetProperties())
{
DescriptionAttribute da = null;
DefaultValueAttribute dv = null;
foreach (Attribute attr in p.GetCustomAttributes(true))
{
if (attr is DescriptionAttribute)
{
da = (DescriptionAttribute) attr;
}
if (attr is DefaultValueAttribute)
{
dv = (DefaultValueAttribute) attr;
}
}
UInt32 value = 0;
if (da != null && !String.IsNullOrEmpty(da.Description))
{
value = Factory.Instance.SelectByCode(da.Description, 3);
}
if (dv != null && value == 0)
{
value = (UInt32) dv.Value;
}
p.SetValue(this, value, null);
}
}
private UInt32 name;
[Description("name")]
[DefaultValue(41)]
public UInt32 Name
{
get { return this.name; }
set { this.name = value; }
}
(30 more properties)
}
奇妙なことに、このクラスをシリアライズしようとすると、空のノード CustomClass が取得されます。
<CustomClass />
そして、コンストラクターから Init を削除すると、期待どおりに動作します! クラスの完全な xml 表現を取得しますが、もちろん値はありません (すべて値 0)。
<CustomClass>
<Name>0</Name>
...
</CustomClass>
また、Init の本体をコメント アウトすると、上記と同じもの (既定値のもの) が得られます。パブリック メソッド、ヘルパー クラスのすべてで試しましたが、機能しません。つまり、期待される代わりに:
<CustomClass>
<Name>15</Name>
...
</CustomClass>
私は手に入れます
<CustomClass />
このクラスでリフレクションを使用すると、シリアライズができないようです。または要約すると: Init を呼び出すとき、またはプロパティをリフレクションで埋めるとき -> シリアル化が失敗し、このコード部分を削除すると -> シリアル化は機能しますが、もちろん値はありません。
これは本当ですか?そして、誰かが私の解決策の代替案を知っていますか?
説明に基づいてデータベースから自動的に何かを取得する必要があり、これが何も返さない場合は、DefaultValue にフォールバックします...
PS1: XmlSerializer を使用しています
PS2: シリアル化の前にブレークポイントを設定すると、すべてのプロパティが適切な値 (71、72 など) で満たされていることがわかります。