我想控制特定类如何序列化其数据...例如:
[TimeSeriesSerialization(TimeSeriesSerializationType.Dates)]
public TimeSeries DailyValues { get; set; }
[TimeSeriesSerialization(TimeSeriesSerializationType.Normal)]
public TimeSeries IntraDayValues { get; set; }
在这里的示例中,我有一个名为TimeSeries的类,该类具有一个DateTimes列表和一个十进制列表...当我对其进行序列化时,我想做两件事...创建一个JSON字符串,它是一组时间/值对...例如:
{"2018-01-30T09:30:01":9958.2289,"2018-01-30T09:30:02":9958.2284,...}
但是我也希望可以选择将此类序列化为Date值(没有时间)...如此:
{"2018-01-30":9958.2289,"2018-01-31":9958.2284,...}
或仅作为值:
[9958.2289,9958.2284,...]
有帮助吗?
public enum TimeSeriesSerializationType
{
Times,
Dates,
ValuesOnly,
}
public class TimeSeries
{
public List<DateTime> Times = new List<DateTime>();
public List<decimal> Values = new List<decimal>();
public void Add(DateTime time, decimal value)
{
Times.Add(time);
Values.Add(value);
}
public string Serialize(TimeSeriesSerializationType timeSeriesSerializationType)
{
switch (timeSeriesSerializationType)
{
case TimeSeriesSerializationType.Dates:
{
var data = new Dictionary<DateTime, decimal>();
for (var i = 0; i < Times.Count; i++)
{
if (!data.ContainsKey(Times[i])) // duplicate dates???
data.Add(Times[i], Values[i]);
}
var isoDateTimeConverter = new IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-dd" };
var json = JsonConvert.SerializeObject(data, Formatting.None, isoDateTimeConverter);
return json;
}
case TimeSeriesSerializationType.ValuesOnly:
{
var json = JsonConvert.SerializeObject(Values, Formatting.None);
return json;
}
default:
{
var data = new Dictionary<DateTime, decimal>();
for (var i = 0; i < Times.Count; i++)
{
if (!data.ContainsKey(Times[i])) // duplicate times???
data.Add(Times[i], Values[i]);
}
var isoDateTimeConverter = new IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-ddTHH\\:mm\\:ss.fffffffzzz" };
var json = JsonConvert.SerializeObject(data, Formatting.None, isoDateTimeConverter);
return json;
}
}
}
public void Deserialize(string str)
{
if (string.IsNullOrEmpty(str)) return;
var data = JsonConvert.DeserializeObject<Dictionary<DateTime, decimal>>(str);
if (data.Count <= 0) return;
foreach (var d in data)
this.Add(d.Key, d.Value);
}
}
答案 0 :(得分:0)
我认为您已经拥有了大部分所需的东西。
缺少的是属性本身。
您可以这样定义它(您可以阅读有关AttributeUsage-Attribute here的更多信息):
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
class TimeSeriesSerializationAttribute : Attribute
{
public TimeSeriesSerializationType SerializationType { get; }
public TimeSeriesSerializationAttribute(TimeSeriesSerializationType timeSeriesSerializationType)
{
SerializationType = timeSeriesSerializationType;
}
}
现在,您可以像写过一样在属性上方添加这些属性。
评估部分的时间。您可以使用类似的方法读取所有属性,并使用它们来序列化您的TimeSeries。
顺便说一句,如果您获得的属性结果为null,则不会设置该属性。您可以完全跳过该属性,也可以使用默认的SerializationType,无论您是否需要。
public static void SerializeToSomewhere(YourClassWithTimeSeries instance) {
// get all public, instance properties
IEnumerable<PropertyInfo> allProps = typeof(YourClassWithTimeSeries).GetProperties(BindingFlags.Public | BindingFlags.Instance);
// only take TimeSeries-properties
IEnumerable<PropertyInfo> timeSeriesProps = allProps.Where(p => p.PropertyType == typeof(TimeSeries));
foreach (PropertyInfo property in timeSeriesProps)
{
// get the attribute
TimeSeriesSerializationAttribute attribute = property.GetCustomAttribute<TimeSeriesSerializationAttribute>();
if (attribute == null) continue; // or do something else like use a default SerializationType
// get the value
TimeSeries value = (TimeSeries)property.GetValue(instance, null);
// serialize using the type from the attribute
string serializedValue = value.Serialize(attribute.SerializationType);
// Do whatever with the serialized value (for example save it to a file or whatever)
}
}
希望这对您有所帮助。如果您需要其他信息,也有很多属性教程和文档。我还将尝试回答您可能有的问题,请随时提出。
编辑:
小东西要添加。在您的代码中,TimeSeries类公开了公共字段“时间和值”。你不应该那样做。
而不是这样做:
public List<DateTime> Times = new List<DateTime>();
public List<decimal> Values = new List<decimal>();
您应该这样做。这样可以防止您不小心从班级内部或外部再次分配它。
public List<DateTime> Times { get; } = new List<DateTime>();
public List<decimal> Values { get; } = new List<decimal>();
答案 1 :(得分:0)
更行人但有效的方法(对于json)...
[JsonIgnore]
public PriceSeries DailyValues { get; set; }
[JsonProperty(PropertyName = "DailyValues")]
public string DailyValuesSerialized {
get
{
return (DailyValues == null) ?
null :
DailyValues.Serialize(TimeSeriesSerializationType.ValuesOnly);
}
set
{
DailyValues = (value == null) ? null : new PriceSeries(value);
}
}
[JsonIgnore]
public PriceSeries IntraDayValues { get; set; }
[JsonProperty(PropertyName = "IntraDayValues")]
public string IntraDayValuesSerialized
{
get
{
return (IntraDayValues == null) ?
null :
IntraDayValues.Serialize(TimeSeriesSerializationType.Normal);
}
set
{
IntraDayValues = (value == null) ? null : new PriceSeries(value);
}
}
或者这个(对于数据库)...
[NotMapped]
public PriceSeries DailyValues { get; set; }
[Column("DailyValues")]
public string DailyValuesSerialized
{
get
{
return (DailyValues == null) ?
null :
DailyValues.Serialize(TimeSeriesSerializationType.ValuesOnly);
}
set
{
DailyValues = (value == null) ? null : new PriceSeries(value);
}
}
[NotMapped]
public PriceSeries IntraDayValues { get; set; }
[Column("IntraDayValues")]
public string IntraDayValuesSerialized
{
get
{
return (IntraDayValues == null) ?
null :
IntraDayValues.Serialize(TimeSeriesSerializationType.Normal);
}
set
{
IntraDayValues = (value == null) ? null : new PriceSeries(value);
}
}