我在WP7应用程序中使用Sterling DB并尝试实现自定义序列化程序,希望可以提高性能。
我将提供一个示例(请原谅所有格式,尝试压缩它以保持它的小)。给定一种继承List<string>:
public class TypedList : List<string>
{
public Guid ObjectId { get; set; }
public TypedList() { }
public TypedList(int count) : base(count) { }
}
它是串行器:
public class TypedListSerializer : Wintellect.Sterling.Serialization.BaseSerializer
{
public override bool CanSerialize(Type targetType)
{
return targetType.Equals(typeof(TypedList));
}
public override object Deserialize(Type type, BinaryReader reader)
{
int count = reader.ReadInt32();
var list = new TypedList(count);
for (int i = 0; i < count; i++)
list.Add(reader.ReadString());
return list;
}
public override void Serialize(object target, BinaryWriter writer)
{
var list = (TypedList)target;
writer.Write(list.Count);
foreach (string s in list)
writer.Write(s);
}
}
我使用引擎注册序列化器:
_engine = new SterlingEngine();
_engine.SterlingDatabase.RegisterSerializer<TypedListSerializer>();
_engine.Activate();
假设有一个TypedList
类型的表。现在,当我尝试在Sterling实例上保存/加载此类型时:
// _instance is a class that inherits BaseDatabaseInstance from the Sterling code.
_instance.Save<TypedList>(list);
_instance.Flush();
_instance.Load<TypedList>(g); // g is Guid.
它调用CanSerialize
,但Type
给出的是来自T
List<T>
的{{1}},即我继承的类。如果您将string
更改为int
,则会告诉我类型为int
。
还有其他人有这个问题吗?这是一个Sterling问题还是一个关于泛型的类型信息?
更新 :根据Marc关于继承的建议,我将我的类型修改为以下内容:
public class TypedList
{
public Guid ObjectId { get; set; }
public List<int> Items { get; set; }
public TypedList()
{
Items = new List<int>();
}
}
序列化程序似乎正在检查 TypedList
的属性而不是类型本身。我猜这现在是我如何使用Sterling的错。我的表注册行如下所示:
protected override List<ITableDefinition> RegisterTables()
{
return new List<ITableDefinition>
{
CreateTableDefinition<TypedList, Guid>(l => l.ObjectId)
};
}
答案 0 :(得分:3)
仅仅是为了它的价值 - Sterling希望完全控制“顶级”实体,这样它就可以构建键,索引和其他需要运行的部分。这就是为什么它从不为顶级实体(您定义为具有索引和键的实体)调用自定义序列化程序的原因。自定义序列化程序适用于这些表的属性。上面的修复是正确的,因为它现在将列表视为属性而不是它尝试序列化的顶级“项目”。
答案 1 :(得分:1)
我不熟悉那个序列化程序,但序列化程序在列表中“接管”并不常见 - 使用内置机制表示[n]项,但是使用常规管道来表示每个项目转。我怀疑(纯粹是预感)这就是这里发生的事情。
请注意,作为结果(与许多其他序列化器一样),在列表本身上具有值(即ObjectId
)可能是不可取的。我通常会使用封装而不是继承:
public class TypedList
{
public Guid ObjectId { get; set; }
private readonly List<string> items = new List<string>();
public List<string> Items { get { return items; } }
}
即。 拥有 ObjectId且 列表的内容,而不是拥有 ObjectId且 的内容列表。