【问题标题】:Serialization of enum fails枚举的序列化失败
【发布时间】:2012-03-02 20:08:56
【问题描述】:

我为此使用 .NET 3.5。

我有一个枚举:

[System.SerializableAttribute()]
public enum MyEnum
{
    [System.Xml.Serialization.XmlEnumAttribute("035")]
    Item1,
    Item2
}

我在一个类中使用这个枚举:

[System.SerializableAttribute()]
public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public MyEnum MyEnum { get; set; }
}

现在我想创建一个新的 Eplomyee 实例,通过从字符串转换来设置 MyEnum 属性。 然后将其序列化并保存在一个文件中。

Employee bob = new Employee() {Id = 1, Name = "Bob"};
bob.MyEnum = (MijnEnum)Enum.Parse(typeof(MyEnum), string.Format(CultureInfo.InvariantCulture, "{0}", "035"));

XmlSerializer serializer = new XmlSerializer(typeof(Employee));
FileInfo fi = new FileInfo(@"C:\myfile.xml");
using (FileStream stream = fi.OpenWrite())
{
    XmlWriterSettings xmlWriterSettings = new XmlWriterSettings { Encoding = Encoding.UTF8, OmitXmlDeclaration = true, Indent = true };
    using (XmlWriter writer = XmlWriter.Create(stream, xmlWriterSettings))
    {
        serializer.Serialize(writer, bob); // this is place where it goes wrong
    }
}

如果我对此进行调试,我会看到 bob.MyEnum 的值是 35

当我尝试序列化时,我得到一个异常:

生成 XML 文档时出错。

实例验证错误:“35”不是 WindowsFormsApplication.MyEnum。

出了什么问题,我该如何解决?

【问题讨论】:

  • 你做错了。特别是Enum.Parse
  • 您是否尝试在枚举声明中指定:Item1 = 25,
  • 你知道你可以只使用 [Serializable] 而不是 [System.SerializableAttribute()]?
  • @leppie:启发我。也许这可以解决我的问题。
  • @Botz3000:是的,我知道。该属性是自动生成的,因此是全名...

标签: c# enums xml-serialization


【解决方案1】:

让我们开始吧:

[System.SerializableAttribute()] // useless, valuetype is implicitly so
public enum MyEnum
{
    [System.Xml.Serialization.XmlEnumAttribute("035")]
    Item1,
    Item2
}

现在XmlEnumAttribute 控制该值如何在 XML 中序列化和反序列化。

它与您的代码的其余部分无关!(对不起,大写,但似乎没有其他人明白这一点)。

所以当MyEnum.Item1 的值被序列化时,将发出“035”。

现在的问题是你想如何分配这个。

这很简单。就像你通常做的那样分配。这些属性都不会改变普通代码的语义,一切都保持不变。

例子:

Employee bob = new Employee() {Id = 1, Name = "Bob", MyEnum = MyEnum.Item1};

这里绝对没有理由考虑Enum.Parse。枚举类型和值是静态已知的。

如果您确实想使用Enum.Parse,请像往常一样使用它,例如:

Enum.Parse(typeof(MyEnum), "Item1")

【讨论】:

  • 我必须将字符串解析为枚举。好的,在我的示例中,我在这里硬编码了“035”。但在我的程序中,它来自一个变量。
  • @Natrium:如果是变量,赋值即可!您正在以一种非常复杂且不需要的方式做事。
  • @Natrium:什么不起作用?告诉我,我真的不知道你要做什么了。
  • @Natrium:我仍在等待(并尝试并愿意)帮助您。请解释哪里出了问题。
  • @leppie 最后你也在做同样的事情。我认为您需要考虑该否决票。您只能通过两种方式解析 EnumEnum.ParseEnum.TryParse 从字符串中解析。如果有其他方法,可以提一下。
【解决方案2】:

发生这种情况是因为 Enums 在内部存储为 int。因此,您的声明 bob.MyEnum = (MijnEnum)Enum.Parse(typeof(MyEnum), string.Format(CultureInfo.InvariantCulture, "{0}", "035")); 运行没有问题。如果您调试,bob.MyEnum 的值为35。当您反序列化它时,反序列化器会搜索匹配的 enum 与 int 值 35,因为您正在指定 Item1 和 Item2,所以它不存在。因此你会得到一个错误。

这会起作用

 bob.MyEnum = (MyEnum)Enum.Parse(typeof(MyEnum), "35");

 public enum MyEnum {
   Item1 = 35,
   Item2
 }

理想情况下你应该这样做

 bob.MyEnum = (MyEnum)Enum.Parse(typeof(MyEnum), "Single");

 public enum MyEnum {
   [System.Xml.Serialization.XmlEnumAttribute("Single")]
   Item1,
   Item2
 }

希望这对您有所帮助。

【讨论】:

  • 正如我没有得到你。我没有给出任何解决方案。我解释了它发生的原因。
  • @leppie 用户的输入是一个字符串。我认为你们这里的 cmets 有点粗鲁或冒犯。国际海事组织你的声誉不会给你这个特权。
  • @onof:对不起,如果我试图指出这些答案的不正确性,原因很简单,比如没有阅读问题和理解问题。我现在已经发布了一个答案。我认为不需要它,但似乎我错了。
  • 虽然我对 sn-p 1 的工作感到有点惊讶(你得到了你的反对票;p),但第二个 sn-p 仍然不起作用或做任何 OP 没有尝试过的事情。跨度>
【解决方案3】:

我改变了枚举解析。

我使用反射将字符串解析为枚举,如本文所述:http://www.codeguru.com/csharp/csharp/cs_syntax/enumerations/article.php/c5869

现在它可以工作了。

【讨论】:

  • 虽然我同意上述方法应该可行,但对于一项简单的任务来说,它似乎是不必要的复杂。
  • 你知道这与 Enum.Parse 有何不同吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-16
  • 2020-02-27
  • 1970-01-01
  • 1970-01-01
  • 2012-05-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多