.net 如何将枚举值序列化为 int?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/506368/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 11:09:36  来源:igfitidea点击:

How do I serialize an enum value as an int?

.netenumsxml-serialization

提问by Espo

I want to serialize my enum-value as an int, but i only get the name.

我想将我的枚举值序列化为 int,但我只得到了名称。

Here is my (sample) class and enum:

这是我的(示例)类和枚举:

public class Request {
    public RequestType request;
}

public enum RequestType
{
    Booking = 1,
    Confirmation = 2,
    PreBooking = 4,
    PreBookingConfirmation = 5,
    BookingStatus = 6
}

And the code (just to be sure i'm not doing it wrong)

和代码(只是为了确保我没有做错)

Request req = new Request();
req.request = RequestType.Confirmation;
XmlSerializer xml = new XmlSerializer(req.GetType());
StringWriter writer = new StringWriter();
xml.Serialize(writer, req);
textBox1.Text = writer.ToString();

This answer(to another question) seems to indicate that enums should serialize to ints as default, but it doesn't seem to do that. Here is my output:

这个答案(对另一个问题)似乎表明枚举应该默认序列化为整数,但它似乎并没有这样做。这是我的输出:

<?xml version="1.0" encoding="utf-16"?>
<Request xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <request>Confirmation</request>
</Request>

I have been able to serialize as the value by putting an "[XmlEnum("X")]" attribute on every value, but this just seems wrong.

我已经能够通过在每个值上放置一个“[XmlEnum(“X”)]”属性来序列化为值,但这似乎是错误的。

采纳答案by Marc Gravell

Most of the time, people want names, not ints. You could add a shim property for the purpose?

大多数时候,人们想要的是名字,而不是整数。您可以为此目的添加垫片属性吗?

[XmlIgnore]
public MyEnum Foo {get;set;}

[XmlElement("Foo")]
[EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
public int FooInt32 {
    get {return (int)Foo;}
    set {Foo = (MyEnum)value;}
}

Or you could use IXmlSerializable, but that is lots of work.

或者您可以使用IXmlSerializable,但这需要大量工作。

回答by miha

The easiest way is to use [XmlEnum] attribute like so:

最简单的方法是使用 [XmlEnum] 属性,如下所示:

[Serializable]
public enum EnumToSerialize
{
    [XmlEnum("1")]
    One = 1,
    [XmlEnum("2")]
    Two = 2
}

This will serialize into XML (say that the parent class is CustomClass) like so:

这将序列化为 XML(假设父类是 CustomClass),如下所示:

<CustomClass>
  <EnumValue>2</EnumValue>
</CustomClass>

回答by Peter McG

Please see the full example Console Application program below for an interesting way to achieve what you're looking for using the DataContractSerializer:

请参阅下面的完整示例控制台应用程序,了解使用 DataContractSerializer 实现您正在寻找的内容的有趣方式:

using System;
using System.IO;
using System.Runtime.Serialization;

namespace ConsoleApplication1
{
    [DataContract(Namespace="petermcg.wordpress.com")]
    public class Request
    {
        [DataMember(EmitDefaultValue = false)]
        public RequestType request;
    }

    [DataContract(Namespace = "petermcg.wordpress.com")]
    public enum RequestType
    {
        [EnumMember(Value = "1")]
        Booking = 1,
        [EnumMember(Value = "2")]
        Confirmation = 2,
        [EnumMember(Value = "4")]
        PreBooking = 4,
        [EnumMember(Value = "5")]
        PreBookingConfirmation = 5,
        [EnumMember(Value = "6")]
        BookingStatus = 6
    }

    class Program
    {
        static void Main(string[] args)
        {
            DataContractSerializer serializer = new DataContractSerializer(typeof(Request));

            // Create Request object
            Request req = new Request();
            req.request = RequestType.Confirmation;

            // Serialize to File
            using (FileStream fileStream = new FileStream("request.txt", FileMode.Create))
            {
                serializer.WriteObject(fileStream, req);
            }

            // Reset for testing
            req = null;

            // Deserialize from File
            using (FileStream fileStream = new FileStream("request.txt", FileMode.Open))
            {
                req = serializer.ReadObject(fileStream) as Request;
            }

            // Writes True
            Console.WriteLine(req.request == RequestType.Confirmation);
        }
    }
}

The contents of request.txt are as follows after the call to WriteObject:

调用WriteObject后request.txt的内容如下:

<Request xmlns="petermcg.wordpress.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <request>2</request>
</Request>

You'll need a reference to the System.Runtime.Serialization.dll assembly for DataContractSerializer.

您将需要对 DataContractSerializer 的 System.Runtime.Serialization.dll 程序集的引用。

回答by Abhishek

using System.Xml.Serialization;

public class Request
{    
    [XmlIgnore()]
    public RequestType request;

    public int RequestTypeValue
    {
      get 
      {
        return (int)request;
      } 
      set
      {
        request=(RequestType)value; 
      }
    }
}

public enum RequestType
{
    Booking = 1,
    Confirmation = 2,
    PreBooking = 4,
    PreBookingConfirmation = 5,
    BookingStatus = 6
}

The above approach worked for me.

上述方法对我有用。

回答by Glenn

Take a look at the System.Enum class. The Parse method converts a string or int representation into the Enum object and the ToString method converts the Enum object to a string which can be serialized.

看看 System.Enum 类。Parse 方法将字符串或 int 表示转换为 Enum 对象,ToString 方法将 Enum 对象转换为可以序列化的字符串。

回答by Adriaan Davel

Since you are assigning explicit non-sequential values to the enum options I am assuming you want to be able to specify more than one value at a time (binary flags), then the accepted answer is your only option. Passing in PreBooking | PreBookingConfirmation will have an integer value of 9 and the serializer will not be able to deserialize it, casting it with a shim property however will work well. Or maybe you just missed the 3 value :)

由于您将显式非顺序值分配给枚举选项,我假设您希望能够一次指定多个值(二进制标志),那么接受的答案是您唯一的选择。预售通行证| PreBookingConfirmation 的整数值为 9,序列化程序将无法反序列化它,但使用 shim 属性将其转换会很好地工作。或者,您可能只是错过了 3 个值:)