使用 ServiceStack.Text 反序列化派生泛型类型时出错

Error using ServiceStack.Text to deserialize derived generic type

我在将对象存储到 Redis 之前使用 ServiceStack.Text 到 serialize/deserialize 对象,但是我遇到了一些对象,它们不会按预期反序列化。

我有一个基类型(一些遗留代码,许多项目都使用这个基类型)和一个 属性 类型的对象。后来添加了基本类型的通用版本,将 属性 公开为通用类型。

使用 ServiceStack.Text 序列化和反序列化泛型类型在基础 class(类型对象)上设置 属性,而不是在派生的 [=44= 上设置更具体的类型].

重现错误的简单控制台应用程序如下所示:

class Program
{
    public class Base<T> : Base
    {
        //hide the Value property on the base class
        public new T Value { get; set; }
    }

    public class Base
    {
        public object Value { get; set; }
    }

    static void Main(string[] args)
    {
        var a = new Base<List<string>>()
        {
            Value = new List<string>() { "one", "two", "three" },
        };

        var serialized = TypeSerializer.SerializeToString(a);
        var deserialized = TypeSerializer.DeserializeFromString<Base<List<string>>>(serialized);

        //throws a null ref exception
        Console.WriteLine(deserialized.Value.Count);
    }
}

反序列化后设置断点,Visual Studio显示base.Value的对象为List,其值为序列化列表,但我的Base上的值为属性 > class 为空。

Screenshot of debugger in Visual Studio

有什么方法可以配置 TypeSerializer(或 JsonSerializer)以正确设置为更具体的 属性 而不是基于 class 的 属性?

感谢任何帮助。


更新

根据答案,我通过使 Base<T>Base 继承自新的抽象基础 class 来解决它,如下所示:

public abstract class DummyBase
{
    public string Test { get; set; } = "Test";
}

public class BaseResponse<T> : DummyBase
{
    public T Value { get; set; }
}

public class BaseResponse : DummyBase
{
    public object Value { get; set; }
}

即使 Base.Value 被隐藏,反射仍然可见(例如 a.GetType().GetProperties()。这可能是问题所在。

以下似乎可行。 Base<T> 中的 getter 和 setter 只是包裹了 Base.ValueDummyBase<T> 是让 ServiceStack 将字符串反序列化为正确类型所必需的。

class Program
{
    public static void Main (string[] args)
    {
        var a = new Base<List<string>>()
        {
            Value = new List<string> { "one", "two", "three" },
        };

        var serialized = TypeSerializer.SerializeToString(a);
        var deserialized = TypeSerializer.DeserializeFromString<DummyBase<List<string>>>(serialized);

        // no longer throws a null ref exception
        Console.WriteLine(deserialized.Value.Count);
    }
}

public class DummyBase<T> 
{
    public T Value { get; set; }
}

public class Base<T> : Base
{ 
    public new T Value 
    {
        get { return (T)base.Value; }
        set { base.Value = value; }
    }
}

public class Base
{
    public object Value { get; set; }
}

当然,如果 Base<T> 没有继承自 Base,那么这一切都不是必需的。