gpt4 book ai didi

c# - 如何将类序列化为属性?

转载 作者:太空宇宙 更新时间:2023-11-03 15:51:00 24 4
gpt4 key购买 nike

我正在尝试将一个类序列化为一个属性。这是用例:我需要在 xml 配置文件中存储大量工程参数。涉及科学记数法,客户要求输入的值保持用户输入的形式。例如,如果有人输入“5.3e-1”,那么它必须保持原样,不能转换为“0.53”。为此我创建了一个Params类,它同时存储了输入的字符串和double值(其实存储double值只是为了后面的处理效率)。诀窍是:我只希望字符串值被序列化,并且我希望将其序列化为一个属性。

例如,如果一个对象包含两个参数 A 和 B,其中字符串值为 A.stringVal = "1.2e5"和 B.stringVal = "2.0"那么我想:

public class MyObject
{
[XmlAttribute]
public MyParam A { get; set; }

[XmlAttribute]
public MyParam B { get; set; }

...more stuff...
}

序列化为:

<myObject A="1.2e5" B="2.0">
more stuff...
</myObject>

我的问题与一个问题非常相似 here .与他不同,我对实现 IXmlSerializable 没问题(并且更愿意这样做),但我就是无法让它发挥作用。当我尝试序列化它时,我得到一个神秘的异常,说“有错误反射类型。”我做错了什么?

  public class MyParam : IXmlSerializable
{
string name;
string stringVal;
double doubleVal;

public string Val
{
get
{
return stringVal;
}
set
{
stringVal = value;
doubleVal = double.Parse(value);
}
}

public double DoubleVal
{
get
{
return doubleVal;
}
set
{
doubleVal = value;
stringVal = value.ToString();
}
}

public MyParam(string name)
{
this.name = name;
this.stringVal = string.Empty;
this.doubleVal = double.NaN;
}

public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}

public void ReadXml(System.Xml.XmlReader reader)
{
throw new NotImplementedException();
}

public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteAttributeString(name, stringVal);
}
}

最佳答案

要获得您想要的内容,您需要控制包含属性的容器的序列化,而不是属性本身。但是,您仍然可以将序列化代码封装在属性中,请参见下文。

public class MyObject : IXmlSerializable
{
public MyParam A { get; set; }

public MyParam B { get; set; }

public XmlSchema GetSchema()
{
return null;
}

public void ReadXml(XmlReader reader)
{
throw new NotImplementedException();
}

public void WriteXml(XmlWriter writer)
{
//Call each properties "WriteAttribute" call.
A.WriteAttribute(writer);
B.WriteAttribute(writer);
}
}

public class MyParam
{
string name;
string stringVal;
double doubleVal;

public string Val
{
get
{
return stringVal;
}
set
{
stringVal = value;
doubleVal = double.Parse(value);
}
}

public double DoubleVal
{
get
{
return doubleVal;
}
set
{
doubleVal = value;
stringVal = value.ToString();
}
}

public MyParam(string name)
{
this.name = name;
this.stringVal = string.Empty;
this.doubleVal = double.NaN;
}

internal void WriteAttribute(XmlWriter writer)
{
writer.WriteAttributeString(name, stringVal);
}
}

class Program
{
static void Main(string[] args)
{
var test = new MyObject()
{
A = new MyParam("A"),
B = new MyParam("B"),
};

test.A.Val = "1.2e5";
test.B.Val = "2.0";

var ser = new XmlSerializer(typeof(MyObject));
var sb = new StringBuilder();
using (var stream = new StringWriter(sb))
{
ser.Serialize(stream, test);
}

Console.WriteLine(sb);
Console.ReadLine();
}
}

输出

<?xml version="1.0" encoding="utf-16"?>
<MyObject A="1.2e5" B="2.0" />

如果您不需要属性本身中的属性名称,您可以将代码修改为以下内容。

public class MyObject : IXmlSerializable
{
//....

public void WriteXml(XmlWriter writer)
{
//Call each properties "WriteAttribute" call.
A.WriteAttribute(writer, "A");
B.WriteAttribute(writer, "B");
}
}

public class MyParam
{
//...

public MyParam()
{
this.stringVal = string.Empty;
this.doubleVal = double.NaN;
}

internal void WriteAttribute(XmlWriter writer, string name)
{
writer.WriteAttributeString(name, stringVal);
}
}

关于c# - 如何将类序列化为属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25813092/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com