オブジェクトをシリアル化するためのユーティリティ関数を作成しようとしています。通常、シリアル化は次のように行われます。
[Serializable]
public CoolCat : ISerializable
{
public string Name;
public void CoolCar(SerializationInfo info, StreamingContext context)
{
Name = (string)info.GetValue("Name", typeof(string));
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Name", Name);
}
}
ただし、次のことができるようにしたいです。
[Serializable]
public CoolCat : ISerializable
{
public string Name;
public void CoolCar(SerializationInfo info, StreamingContext context)
{
Name = info.GetValue<string>(() => Name);
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue<string>(() => Name);
}
}
私は次の 2 つの方法でこれを行います。
これは値を逆シリアル化するためのものです:
public static T GetValue<T>(this SerializationInfo Source, Expression<Func<T>> MemberExpression)
{
string Name = ((MemberExpression)MemberExpression.Body).Member.Name;
return (T)Source.GetValue(Name, typeof(T));
}
そしてこれは値をシリアライズするためのものです:
public static void AddValue<T>(this SerializationInfo Source, Expression<Func<T>> MemberExpression)
{
MemberExpression Body = MemberExpression.Body as MemberExpression;
if (Body == null)
{
UnaryExpression UnaryBody = MemberExpression.Body as UnaryExpression;
if (UnaryBody != null)
{
Body = UnaryBody.Operand as MemberExpression;
}
else
{
throw new ArgumentException("Expression is not a MemberExpression", "MemberExpression");
}
}
string Name = Body.Member.Name;
if (Body.Member is FieldInfo)
{
T Value = (T)((FieldInfo)Body.Member).GetValue(((ConstantExpression)Body.Expression).Value);
Source.AddValue(Name, Value, typeof(T));
}
else if (Body.Member is PropertyInfo)
{
T Value = (T)((PropertyInfo)Body.Member).GetValue(((ConstantExpression)Body.Expression, null);
Source.AddValue(Name, Value, typeof(T));
}
else
{
throw new ArgumentException("Expression must refer to only a Field or a Property", "MemberExpression");
}
}
Body.Member がプロパティの場合に値を取得しようとすると、例外が発生します (フィールドの場合は正常に動作します)。どうすればこれを入手できますか?
その他の質問 - 1) 私が取っているアプローチに問題はありますか? 2) おそらくこのすべてを行うためのより良い方法はありますか? 3) Body.Member はいつ FieldInfo になり、いつ PropertyInfo になりますか?
これは私の以前の質問の延長のようなものです