gpt4 book ai didi

c# - 使用可以是不同枚举类型的通用枚举序列化一个类

转载 作者:行者123 更新时间:2023-11-30 23:12:42 27 4
gpt4 key购买 nike

我正在尝试设计一个允许用户在 XML 中指定枚举类型的应用程序,然后应用程序将执行与该枚举相关的特定方法(使用字典)。我被 XML 的枚举部分挂断了。

public class TESTCLASS
{
private Enum _MethodType;

[XmlElement(Order = 1, ElementName = "MethodType")]
public Enum MethodType
{
get { return _MethodType; }
set { _MethodType = value; }
}
public TESTCLASS() { }

public TESTCLASS(Enummies.BigMethods bigM)
{
MethodType = bigM;
}
public TESTCLASS(Enummies.SmallMethods smallM)
{
MethodType = smallM;
}
}

public class Enummies
{
public enum BigMethods { BIG_ONE, BIG_TWO, BIG_THREE }
public enum SmallMethods { SMALL_ONE, SMALL_TWO, SMALL_THREE }
}

然后尝试序列化 TESTCLASS 导致异常:

string p = "C:\\testclass.xml";
TESTCLASS testclass = new TESTCLASS(Enummies.BigMethods.BIG_ONE);
TestSerializer<TESTCLASS>.Serialize(p, testclass);

System.InvalidOperationException: The type Enummies+BigMethods may not be used in this context.

我的序列化方法是这样的:

public class TestSerializer<T> where T: class
{
public static void Serialize(string path, T type)
{
var serializer = new XmlSerializer(type.GetType());
using (var writer = new FileStream(path, FileMode.Create))
{
serializer.Serialize(writer, type);
}
}

public static T Deserialize(string path)
{
T type;
var serializer = new XmlSerializer(typeof(T));
using (var reader = XmlReader.Create(path))
{
type = serializer.Deserialize(reader) as T;
}
return type;
}
}

我尝试在 MethodType Getter 中包含一些检查/转换,但这会导致相同的错误。

    public Enum MethodType
{
get
{
if (_MethodType is Enummies.BigMethods) return (Enummies.BigMethods)_MethodType;
if (_MethodType is Enummies.SmallMethods) return (Enummies.SmallMethods)_MethodType;
throw new Exception("UNKNOWN ENUMMIES TYPE");
}
set { _MethodType = value; }
}

最佳答案

当我尝试使用 XmlSerializer 序列化您的类时,我得到的最里面的异常是:

Message="System.Enum is an unsupported type. Please use [XmlIgnore] attribute to exclude members of this type from serialization graph."

这是不言自明的:您不能序列化类型为抽象类型的成员 System.Enum .

但是,您可以序列化 System.Object 类型的成员 前提是可能遇到的所有可能类型的值都使用 [XmlInclude(typeof(T))] 静态声明. 因此您可以按如下方式修改您的类型:

// Include all possible types of Enum that might be serialized
[XmlInclude(typeof(Enummies.BigMethods))]
[XmlInclude(typeof(Enummies.SmallMethods))]
public class TESTCLASS
{
private Enum _MethodType;

// Surrogate object property for MethodObject required by XmlSerializer
[XmlElement(Order = 1, ElementName = "MethodType")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
public object MethodTypeObject
{
get { return MethodType; }
set { MethodType = (Enum)value; }
}

// Ignore the Enum member that cannot be serialized directly
[XmlIgnore]
public Enum MethodType
{
get { return _MethodType; }
set { _MethodType = value; }
}
public TESTCLASS() { }

public TESTCLASS(Enummies.BigMethods bigM)
{
MethodType = bigM;
}
public TESTCLASS(Enummies.SmallMethods smallM)
{
MethodType = smallM;
}
}

XML 将生成如下:

<TESTCLASS xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<MethodType xsi:type="BigMethods">BIG_THREE</MethodType>
</TESTCLASS>

或者

<?xml version="1.0" encoding="utf-16"?>
<TESTCLASS xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<MethodType xsi:type="SmallMethods">SMALL_TWO</MethodType>
</TESTCLASS>

注意到 xsi:type 属性了吗?那是一个 W3C standard attribute元素可以用来显式断言其类型。 Microsoft 使用此属性来表示多态元素的类型信息,如解释的那样 here .

样本 fiddle .

您可能想在 MethodObject 的 setter(而不是 getter)中检查值类型是否为已知的 Enum 类型,但这不是 XML 序列化所必需的.

关于c# - 使用可以是不同枚举类型的通用枚举序列化一个类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43955541/

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