c# - 如何使用 ShouldSerialize[MemberName]() 有条件地序列化对象属性中的元素,其中属性是列表?
问题描述
我有一个类“Hospitalization”,我需要将其序列化为 XML 字符串。该类有一个属性“ActiveDiagnoses”,它是一个类型为“DiagnosisCode”的列表。
在该集合中,只有具有属性 Order 且值小于 3 的元素才应包含在序列化字符串中。
这是一个示例(它无法仅序列化顺序小于 3 的 DiagnosisCodes):
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
namespace XmlConditionalSerializationOnListExample
{
[XmlRoot]
public class Hospitalization
{
public string PatientName { get; set; }
public DateTime AdmitDate { get; set; }
[XmlElement("DiagnosisCode")]
public List<DiagnosisCode> ActiveDiagnoses { get; set; }
}
public class DiagnosisCode
{
public string Code { get; set; }
public string CodeSet { get; set; }
[XmlIgnore]
public int Order { get; set; }
}
class Program
{
static void Main(string[] args)
{
Hospitalization hospitalization = new Hospitalization() { PatientName = "Test Patient", AdmitDate = DateTime.Now.Date };
List<DiagnosisCode> Dxs = new List<DiagnosisCode>()
{
new DiagnosisCode(){Code="Z99.81", CodeSet="ICD10", Order = 1}
,new DiagnosisCode(){Code="Z99.0", CodeSet="ICD10", Order = 2}
,new DiagnosisCode(){Code="Z98.5", CodeSet="ICD10", Order = 3}
};
hospitalization.ActiveDiagnoses = Dxs;
string HospitalizationXml = String.Empty;
XmlSerializer Ser = new XmlSerializer(hospitalization.GetType());
//XmlSerializer Ser = new XmlSerializer(Hospitalization);
using (StringWriter writer = new StringWriter())
{
Ser.Serialize(writer, hospitalization);
HospitalizationXml = writer.ToString();
}
Console.WriteLine("Hospitalization object as represented by XML string:\n{0}", HospitalizationXml);
Console.ReadKey();
}
}
}
我的第一个想法是设置更改我将 Dxs 变量分配为具有 foreach 循环的 ActiveDiagnoses 属性的值的行,该循环将有条件地将 XmlIgnore 属性添加到每个 DiagnosisCode 属性值高于 2 但显然你不能动态地做到这一点。
然后我找到了几个使用 ShouldSerialize() 方法来确定属性是否会被序列化的示例:
我的场景与上面链接的场景之间的区别在于示例 1 为不是 List 的属性添加了 ShouldSerialize() 方法,虽然第二个确实为 List 属性添加了 ShouldSerialize() 方法,但该方法确定天气或不是整个元素列表都被序列化,而不是其中的特定元素。
我尝试将以下方法添加到 DiagnosisCode 类:
public bool ShouldSerializeDiagnosisCode()
{
return Order < 3 ? true : false;
}
然而它没有任何效果。我试图将该方法移至 Hospitalization 类,但正如预期的那样出现编译错误,因为编译器不知道我在 Order 属性中指的是什么。
通过执行以下操作,我确实找到了解决方法:
1:将 Hospitalization 类更改为具有两个 DiagnosisCode 对象列表,其中一个被标记为在序列化为 XML 时被忽略。
[XmlRoot]
public class Hospitalization
{
public string PatientName { get; set; }
public DateTime AdmitDate { get; set; }
[XmlElement("DiagnosisCode")]
public List<DiagnosisCode> ActiveDiagnoses { get; set; }
[XmlIgnore]
public List<DiagnosisCode> NonBillableDiagnoses { get; set; }
}
2:更改我的 Main() 方法以在循环中添加每个诊断,并根据该时间点的 OrderIndex 确定将 DiagnosisCode 添加到两个列表中的哪一个。
//hospitalization.ActiveDiagnoses = Dxs;
hospitalization.ActiveDiagnoses = new List<DiagnosisCode>();
hospitalization.NonBillableDiagnoses = new List<DiagnosisCode>();
foreach (DiagnosisCode dx in Dxs)
{
if (dx.Order < 3)
{
hospitalization.ActiveDiagnoses.Add(dx);
}
else
{
hospitalization.NonBillableDiagnoses.Add(dx);
}
}
该解决方案工作正常,但我想知道是否有一种方法可以按照我如上所述的方式使用 ShouldSerialize 方法。
您可以提供的任何帮助/建议我将不胜感激。
解决方案
这不是该ShouldSerialize
模式的预期目的。如果您需要在序列化之前转换数据,只需在代码中进行,就像您已经在做的那样。
如果您想将其保留在您的Hospitalization
班级中,您可以在属性的 getter 中过滤列表,如下所示:
[XmlRoot]
public class Hospitalization
{
public string PatientName { get; set; }
public DateTime AdmitDate { get; set; }
[XmlIgnore]
public List<DiagnosisCode> ActiveDiagnoses { get; set; }
[XmlElement("DiagnosisCode")]
public List<DiagnosisCode> SerializableDiagnoses { get { return ActiveDiagnoses.Where(d => d.Order <= 2).ToList(); } }
}
推荐阅读
- javascript - Nativescript 简单删除功能
- vba - MS-Access 表单:使用组合框搜索记录,如果找到匹配则更新记录,如果不匹配则开始添加新记录
- ios - 如何从日期字符串 Swift 中隐藏时间
- python - 如何在机器学习中将 .pth 转换为 .pb
- typescript - 尝试找到一种将 blob 上传到 firebase 并使用云功能对其进行编辑的方法
- java - 如何从单个线程分配的堆转储实例中提取?
- python-3.x - Heroku 错误:getaddrinfo ENOTFOUND api.ec2-xx-xxx-xx-xxx.compute-1.amazonaws.com
- c - qsort 比较函数中的 const 限定符
- imagemagick - Magickick.NET-Q8-x64 版本 7.2.4.0 正在构建的处理器项目“MSIL”和处理器参考 Magick.NET-Q8-x64.dl、AMD64 之间不匹配
- angular - 如何使用可选整数 ngx-mask 屏蔽小数