2

我在 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.

它调用 into CanSerialize,但Type给出的是Tfrom List<T>,我继承的类。如果您更改stringint,它会告诉我类型是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)
    };
}
4

2 回答 2

3

仅仅因为它的价值——Sterling 期望完全控制“顶级”实体,这样它就可以构建它需要运行的键、索引和其他部分。这就是为什么它从不为顶级实体(您定义为具有索引和键的实体)调用自定义序列化程序的原因。自定义序列化程序适用于这些表的属性。上面的修复是正确的,因为它现在将列表视为一个属性,而不是它试图序列化的顶级“项目”。

于 2011-08-09T22:19:52.853 回答
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 并且列表的东西。

于 2011-08-02T22:03:44.793 回答