我正在尝试序列化一个由许多继承自IMyDataType
的变量组成的类。
public abstract class IMyDataType<T>
{
protected virtual T Data { get; set; }
public abstract String ToString(String args = null);
public abstract Boolean SetValue(T newValue);
public abstract Boolean CheckValue(T newValue);
public abstract T GetValue();
}
例如,我可能有一个班级MyInteger
public class MyInteger : IMyDataType<int>
{
public int Min { get; protected set; }
public int Max { get; protected set; }
protected override int Data { get; set; }
public MyInteger(int value)
{
Min = int.MinValue;
Max = int.MaxValue;
if (!SetValue(value))
Data = 0;
}
public MyInteger(int min, int value, int max)
{
Min = min;
Max = max;
if (!SetValue(value))
Data = 0;
}
public override Boolean SetValue(int newVal)
{
if (newVal >= Min && newVal <= Max)
{
Data = newVal;
return true;
}
return false;
}
public override Boolean CheckValue(int newVal)
{
return (newVal >= Min && newVal <= Max);
}
public override int GetValue() { return Data; }
public override String ToString(String args = null) { return Data.ToString(args); }
}
每当我尝试序列化IMyDataType
的子类时,变量T Data
从未被序列化,但Min
和Max
是。要将T Data
序列化,我需要做些什么?
编辑:根据DotNetom的回答,我将T Data
的访问修饰符更改为public,这允许将其序列化。虽然,它有理由受到保护。有没有其他方法可以在保持其访问修饰符完整的同时序列化它?
答案 0 :(得分:3)
默认情况下,Json.NET仅使用公共getter序列化属性(请参阅docs)。您的房产数据受到保护:
"0p
为了将其序列化,您应该将其更改为public:
protected virtual T Data { get; set; }
如果无法更改对公共的访问权限,则可以通过实施自定义合同解析程序来序列化非公共项目。关于如何使用它们的样本可以在SO的问题答案中找到 - JSON.Net: Force serialization of all private fields and all fields in sub-classes
答案 1 :(得分:3)
您只需为Data
创建备用私有属性获取器,并使用[JsonProperty]
属性进行标记。这将允许Json.Net“看到”它并将其序列化,而无需更改原始属性的访问修饰符。
public abstract class IMyDataType<T>
{
protected virtual T Data { get; set; }
...
[JsonProperty("Value")]
private T AlternateData
{
get { return Data; }
}
}
小提琴:https://dotnetfiddle.net/0JMZzX
(注意:理论上,您可以使用Data
属性标记受保护的[JsonProperty]
属性本身,而不是创建备用属性getter。但是,这似乎只有在基本属性为在子类中没有重写。一旦覆盖它,该属性由于某种原因不再起作用 - 即使你将属性移动到子类或将它放在基类和子类中。我不确定这是否是一个Json.Net中的错误或故意的。使用替代的getter似乎总是起作用。)