我正在使用XML序列化以特定于另一个应用程序的格式生成文件。其中一个要求是将所有布尔值表示为1或0.我已经研究了一些可能性,包括struct可以轻松无缝地处理这个问题。目前我正在寻找另一个场地,即使用枚举。
public enum BoolEnum
{
[XmlEnum("0")]
False = 0,
[XmlEnum("1")]
True = 1
}
到目前为止,它运行得非常好,而且更清洁。但是(!)我也试图让反序列化变得容易,我只是希望能够处理错误。如果我生成无效标签:
<invalid>2</invalid>
要反序列化为BoolEnum,我在另一个InvalidOperationException中得到一个InvalidOperationException。如何在枚举中捕获该异常?
附录:
反序列化功能:
static void Deserialize<T>(out T result, string sourcePath) where T : class
{
FileStream fileStream = null;
try
{
fileStream = new FileStream(sourcePath, FileMode.Open, FileAccess.Read);
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
result = xmlSerializer.Deserialize(fileStream) as T;
}
finally
{
if (fileStream != null)
fileStream.Close();
}
}
反序列化对象:
public class Test
{
[XmlElement("someboolvalue")
public BoolEnum SomeBoolValue { get; set; }
}
答案 0 :(得分:3)
我只是希望能够处理错误
您可以使用属性将某些属性公开给Xml序列化,并隐藏其他属性。同样,您可以通过Intellisense公开某些属性,并隐藏其他属性。
您可以利用此事实从基础序列化中使用不同的代码可见属性类型。这样您就可以在代码中使用bool
,并在序列化中使用int
。
如果选择此路由,则可以在int
属性的getter / setter方法中添加自定义序列化代码来处理这种情况。 E.g。
[XmlIgnore]
public bool SomeValue { get; set; }
[EditorBrowsable(EditorBrowsableState.Never)]
[XmlElement("SomeValue")]
public int SomeValueForSerialization
{
get
{
return SomeValue ? 1 : 0;
}
set
{
SomeValue = value != 0;
// Or do strict validation, and throw whatever exception you'd like.
// Preferably one the serializer will already throw, tho :)
}
}
答案 1 :(得分:0)
我通常更喜欢将复杂的持久性作为类的一个单独特性。
我使用XElement
和扩展方法的组合来使持久性清晰简洁,例如:
public static int AsZeroOrOneElelementNamed(this bool theBool, string name)
{
return new XElement( name, theBool ? 1 : 0 ) ;
}
然后,在你的类型中:
public XElement AsXml( )
{
return new XElement(@"ThisThing",
_myBoolean.AsZeroOrElementNamed(@"MyBoolean"),
_myString.AsElementNamed(@"MyString"));
}
这消除了XML属性的混乱,使得更清晰,更清晰,并将持久性方面留给了一个只负责序列化的方法。
但是对于非常简单的持久性,例如我不会使用任何属性来混淆我的类型,然后我使用内置的持久性。