【发布时间】:2011-03-04 14:00:59
【问题描述】:
我尝试用BinaryFormatter 序列化DynamicObject 类,但是:
- 输出文件太大,不完全友好
- 循环引用未处理(序列化时卡住)
由于 序列化 DynamicObject 本身意义不大,这是我尝试序列化的类:
[Serializable()]
class Entity
: DynamicObject, ISerializable
{
IDictionary<string, object> values = new Dictionary<string, object>();
public Entity()
{
}
protected Entity(SerializationInfo info, StreamingContext ctx)
{
string fieldName = string.Empty;
object fieldValue = null;
foreach (var field in info)
{
fieldName = field.Name;
fieldValue = field.Value;
if (string.IsNullOrWhiteSpace(fieldName))
continue;
if (fieldValue == null)
continue;
this.values.Add(fieldName, fieldValue);
}
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
this.values.TryGetValue(binder.Name, out result);
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
this.values[binder.Name] = value;
return true;
}
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
foreach (var kvp in this.values)
{
info.AddValue(kvp.Key, kvp.Value);
}
}
}
(我想我可以使用 ExpandoObject,但那是另一回事了。)
这是一个简单的测试程序:
static void Main(string[] args)
{
BinaryFormatter binFmt = new BinaryFormatter();
dynamic obj = new Entity();
dynamic subObj = new Entity();
dynamic obj2 = null;
obj.Value = 100;
obj.Dictionary = new Dictionary<string, int>() { { "la la la", 1000 } };
subObj.Value = 200;
subObj.Name = "SubObject";
obj.Child = subObj;
using (var stream = new FileStream("test.txt", FileMode.OpenOrCreate))
{
binFmt.Serialize(stream, obj);
}
using (var stream = new FileStream("test.txt", FileMode.Open))
{
try
{
obj2 = binFmt.Deserialize(stream);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
Console.ReadLine();
}
在这里和那里放置一些断点帮助我查看了 obj2 的内容,看起来原始数据已正确反序列化,但如果您富有想象力并四处移动数据,则会出现上述缺点。
我查看了 Marc Gravell 的 protobuf-net,但我不确定如何在这种情况下使用它(我什至不确定我是否从存储库中选择了正确的版本,但是嘿)。
我知道代码多于文字,但我认为我无法更好地解释这个场景。请务必告诉我是否可以添加一些内容以使这个问题更清楚。
非常感谢任何帮助。
【问题讨论】:
-
供参考,protobuf-net 目前不支持
dynamic。我建议转移到 DTO 层进行序列化。 -
@Marc - 谢谢,我会调查的。仍然欢迎其他建议。
-
好吧,从长远来看,这是我计划在 protobuf-net 中支持的东西。但我现在不能承诺任何事情。
-
@Raine - 我想出了一个迟来的方法来使用 Marc 的 protobuf-net 处理动态。见下文。
标签: c# serialization dynamic protobuf-net