在不改变原类的情况下,在序列化过程中排除某些属性包含在连载中。另外,我想更改日期格式。当然我可以添加[XmlIgnore],但不允许我更改原始类。我能想到的唯一选择是创建一个新类并复制这两个类之间的所有内容。但这会很丑陋并且需要大量手动代码。由于原始类不是抽象的,是否可以创建子类?我的问题是:如何在不更改原始类的情况下排除某些属性?如何自定义输出XML的日期格式?要求:输入尽可能强序列化的XML应该是可反序列化的提前致谢。对于任何感兴趣的人,我决定使用XmlAttributeOverrides,但使它们具有更强的类型(我讨厌将属性名称键入字符串)。这是我用过的扩展方法:}publicstaticstringBuildString(thisExpressionpropertySelector){switch(propertySelector.NodeType){caseExpressionType.Lambda:LambdaExpressionlambdaExpression=(LambdaExpression)propertySelector;返回BuildString(lambdaExpression.Body);caseExpressionType.Convert:caseExpressionType.Quote:UnaryExpressionunaryExpression=(UnaryExpression)propertySelector;返回BuildString(unaryExpression.Operand);caseExpressionType.MemberAccess:MemberExpressionmemberExpression=(MemberExpression)propertySelector;MemberInfopropertyInfo=memberExpression.Member;if(memberExpression.ExpressionisParameterExpression){returnpropertyInfo.Name;}else{//我们有一个嵌套属性(例如MyType.SomeProperty.SomeNestedProperty)returnBuildString(memberExpression.Expression)+"."+propertyInfo.Name;}default://退出并抛出break;}thrownewInvalidOperationException("表达式必须是成员表达式:"+propertySelector.ToString());然后,要忽略一个属性,我可以优雅地将它添加到忽略列表中:varoverrides=newXmlAttributeOverrides();varignore=newXmlAttributes{XmlIgnore=true};overrides.Add(m=>m.Id,ignore);overrides.Add(m=>m.DateChanged,ignore);输入t=typeof(List);XmlSerializerserial=newXmlSerializer(t,overrides);您可以通过利用XmlSerializer不会将空值序列化到输出的事实来做到这一点排除某些属性因此对于引用类型,您可以省略那些您不希望出现在xml中的属性。得到的xml可以反序列化回同一个类,但是省略的字段显然是null。但是,这对您更改日期格式的愿望没有帮助。为此,您需要创建一个新类,将日期作为所需格式的字符串,或者您可以实现IXmlSerializable,让您完全控制xml。[值得注意的是,日期数据类型在XML中具有标准格式,因此通过更改它,它将不再是XML日期——您可能不在乎]。[根据您的评论进行编辑]还有一个额外的技巧可用于“消失”nullnull类型,但它确实需要更改您的类。在序列化MyProperty时,序列化程序还会检查名为MyProperySpecified的属性是否存在。如果存在并返回false,item属性将不会被序列化:publicclassPerson{[XmlElement]publicstringName{get;放;}[XmlElement]公共日期时间?出生日期{得到;放;}publicboolBirthDateSpecified{get{returnBirthDate.HasValue;}}}如果要添加此属性,则可以删除可为null的类型(如果它为null)。实际上-现在我考虑了一下-根据您的使用场景,这也可能是删除其他属性的有用方法。如果您使用的是XmlSerializer,那么XmlAttributeOverrides可能就是您所需要的。更新:我一直在研究自定义日期格式的可能性,据我所知,没有很好的解决方案。正如其他人所提到的,一种选择是实施IXmlSerializable。这样做的缺点是您要全权负责(取消)序列化整个对象(-graph)。第二种选择也有相当多的缺点,它是对基类进行子类化(您在帖子中提到的替代方案)。通过相当多的管道,从最初的对象转换到最初的对象,以及使用XmlAttributeOverrides您可以构建如下内容:publicclassTest{publicintProp{get;放;}publicDateTimeTheDate{get;放;}}publicclassSubTest:Test{privatestring_customizedDate;publicstringCustomizedDate{get{returnTheDate.ToString("yyyyMMdd");}设置{_customizedDate=值;TheDate=DateTime.ParseExact(_customizedDate,"yyyyMMdd",null);}}publicTestConvert(){returnnewTest(){Prop=this.Prop};}}//序列化XmlAttributeOverridesoverrides=newXmlAttributeOverrides();XmlAttributes属性=newXmlAttributes();attributes.XmlIgnore=true;overrides.Add(typeof(Test),"TheDate",attributes);XmlSerializerxs=newXmlSerializer(typeof(SubTest),overrides);SubTestt=newSubTest(){Prop=10,TheDate=DateTime.Now,CustomizedDate="20120221"};xs.Serialize(fs,t);//反序列化XmlSerializerxs=newXmlSerializer(typeof(SubTest));SubTestt=(SubTest)xs.Deserialize(fs);测试测试t=t.Convert();它不是很漂亮,但它会起作用请注意,在这种情况下,您实际上(反)序列化了SubTest对象。如果确切的类型很重要,那么这也不是一个选择。第一个选项是使用XmlAttributeOverrides类。或者你可以尝试创建一个派生类,并实现IXmlSerializable接口以上是C#学习教程:在不改变原类全部内容的情况下,在序列化过程中排除某些属性,如果对大家有用,需要详细了解一下C#学习教程,希望大家多多关注——publicclassProgram{staticvoidMain(string[]args){StringWritersr1=newStringWriter();varbaseSerializer=newXmlSerializer(typeof(Human));varhuman=newHuman{Age=30,Continent=Continent.America};baseSerializer.Serialize(sr1,human);Console.WriteLine(sr1.ToString());控制台.WriteLine();StringWritersr2=newStringWriter();varspecialSerializer=newXmlSerializer(typeof(SpecialHuman));varspecial=newSpecialHuman(){Age=40,Continent=Continent.Africa};specialSerializer.Serialize(sr2,special);Console.WriteLine(sr2.ToString());控制台.ReadLine();}publicenumContinent{Europe,America,Africa}publicclassHuman{publicintAge{get;放;}publicContinent大陆{get;放;}}[XmlRoot("Human")]publicclassSpecialHuman:Human,IXmlSerializable{#regionIXmlSerializ的实现able//////此方法已保留,不应使用。实现IXmlSerializable接口时,您应该从此方法返回null(在VisualBasic中为Nothing),相反,如果需要指定自定义架构,则将应用于该类。/////////一个描述由该方法生成并由该方法使用的对象的XML表示形式的对象。///publicXmlSchemaGetSchema(){thrownewNotImplementedException();}publicvoidReadXml(XmlReaderreader){thrownewNotImplementedException();}publicvoidWriteXml(XmlWriterwriter){writer.WriteElementString("Age",Age.ToString());开关(大陆){caseContinent.Europe:caseContinent.America:writer.WriteElementString("Continent",this.Continent.ToString());休息;案例Continent.Africa:break;默认值:抛出新的ArgumentOutOfRangeException();}}#endregion}}本文来自网络收集,不代表立场,如涞及奴权请点击右边联系系统管理员删除若转载请注明出处:
