How can I cast int to enum?

后端 未结 30 1522
礼貌的吻别
礼貌的吻别 2020-11-22 00:56

How can an int be cast to an enum in C#?

相关标签:
30条回答
  • 2020-11-22 01:09

    Simple you can cast int to enum

     public enum DaysOfWeeks
        {
            Monday = 1,
            Tuesday = 2,
            Wednesday = 3,
            Thursday = 4,
            Friday = 5,
            Saturday = 6,
            Sunday = 7,
        } 
    
        var day= (DaysOfWeeks)5;
        Console.WriteLine("Day is : {0}", day);
        Console.ReadLine();
    
    0 讨论(0)
  • 2020-11-22 01:10

    In my case, I needed to return the enum from a WCF service. I also needed a friendly name, not just the enum.ToString().

    Here's my WCF Class.

    [DataContract]
    public class EnumMember
    {
        [DataMember]
        public string Description { get; set; }
    
        [DataMember]
        public int Value { get; set; }
    
        public static List<EnumMember> ConvertToList<T>()
        {
            Type type = typeof(T);
    
            if (!type.IsEnum)
            {
                throw new ArgumentException("T must be of type enumeration.");
            }
    
            var members = new List<EnumMember>();
    
            foreach (string item in System.Enum.GetNames(type))
            {
                var enumType = System.Enum.Parse(type, item);
    
                members.Add(
                    new EnumMember() { Description = enumType.GetDescriptionValue(), Value = ((IConvertible)enumType).ToInt32(null) });
            }
    
            return members;
        }
    }
    

    Here's the Extension method that gets the Description from the Enum.

        public static string GetDescriptionValue<T>(this T source)
        {
            FieldInfo fileInfo = source.GetType().GetField(source.ToString());
            DescriptionAttribute[] attributes = (DescriptionAttribute[])fileInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);            
    
            if (attributes != null && attributes.Length > 0)
            {
                return attributes[0].Description;
            }
            else
            {
                return source.ToString();
            }
        }
    

    Implementation:

    return EnumMember.ConvertToList<YourType>();
    
    0 讨论(0)
  • 2020-11-22 01:13

    I am using this piece of code to cast int to my enum:

    if (typeof(YourEnum).IsEnumDefined(valueToCast)) return (YourEnum)valueToCast;
    else { //handle it here, if its not defined }
    

    I find it the best solution.

    0 讨论(0)
  • 2020-11-22 01:13
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text.RegularExpressions;
    
    namespace SamplePrograme
    {
        public class Program
        {
            public enum Suit : int
            {
                Spades = 0,
                Hearts = 1,
                Clubs = 2,
                Diamonds = 3
            }
    
            public static void Main(string[] args)
            {
                //from string
                Console.WriteLine((Suit) Enum.Parse(typeof(Suit), "Clubs"));
    
                //from int
                Console.WriteLine((Suit)1);
    
                //From number you can also
                Console.WriteLine((Suit)Enum.ToObject(typeof(Suit) ,1));
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 01:14

    I think to get a complete answer, people have to know how enums work internally in .NET.

    How stuff works

    An enum in .NET is a structure that maps a set of values (fields) to a basic type (the default is int). However, you can actually choose the integral type that your enum maps to:

    public enum Foo : short
    

    In this case the enum is mapped to the short data type, which means it will be stored in memory as a short and will behave as a short when you cast and use it.

    If you look at it from a IL point of view, a (normal, int) enum looks like this:

    .class public auto ansi serializable sealed BarFlag extends System.Enum
    {
        .custom instance void System.FlagsAttribute::.ctor()
        .custom instance void ComVisibleAttribute::.ctor(bool) = { bool(true) }
    
        .field public static literal valuetype BarFlag AllFlags = int32(0x3fff)
        .field public static literal valuetype BarFlag Foo1 = int32(1)
        .field public static literal valuetype BarFlag Foo2 = int32(0x2000)
    
        // and so on for all flags or enum values
    
        .field public specialname rtspecialname int32 value__
    }
    

    What should get your attention here is that the value__ is stored separately from the enum values. In the case of the enum Foo above, the type of value__ is int16. This basically means that you can store whatever you want in an enum, as long as the types match.

    At this point I'd like to point out that System.Enum is a value type, which basically means that BarFlag will take up 4 bytes in memory and Foo will take up 2 -- e.g. the size of the underlying type (it's actually more complicated than that, but hey...).

    The answer

    So, if you have an integer that you want to map to an enum, the runtime only has to do 2 things: copy the 4 bytes and name it something else (the name of the enum). Copying is implicit because the data is stored as value type - this basically means that if you use unmanaged code, you can simply interchange enums and integers without copying data.

    To make it safe, I think it's a best practice to know that the underlying types are the same or implicitly convertible and to ensure the enum values exist (they aren't checked by default!).

    To see how this works, try the following code:

    public enum MyEnum : int
    {
        Foo = 1,
        Bar = 2,
        Mek = 5
    }
    
    static void Main(string[] args)
    {
        var e1 = (MyEnum)5;
        var e2 = (MyEnum)6;
    
        Console.WriteLine("{0} {1}", e1, e2);
        Console.ReadLine();
    }
    

    Note that casting to e2 also works! From the compiler perspective above this makes sense: the value__ field is simply filled with either 5 or 6 and when Console.WriteLine calls ToString(), the name of e1 is resolved while the name of e2 is not.

    If that's not what you intended, use Enum.IsDefined(typeof(MyEnum), 6) to check if the value you are casting maps to a defined enum.

    Also note that I'm explicit about the underlying type of the enum, even though the compiler actually checks this. I'm doing this to ensure I don't run into any surprises down the road. To see these surprises in action, you can use the following code (actually I've seen this happen a lot in database code):

    public enum MyEnum : short
    {
        Mek = 5
    }
    
    static void Main(string[] args)
    {
        var e1 = (MyEnum)32769; // will not compile, out of bounds for a short
    
        object o = 5;
        var e2 = (MyEnum)o;     // will throw at runtime, because o is of type int
    
        Console.WriteLine("{0} {1}", e1, e2);
        Console.ReadLine();
    }
    
    0 讨论(0)
  • 2020-11-22 01:15

    Slightly getting away from the original question, but I found an answer to Stack Overflow question Get int value from enum useful. Create a static class with public const int properties, allowing you to easily collect together a bunch of related int constants, and then not have to cast them to int when using them.

    public static class Question
    {
        public static readonly int Role = 2;
        public static readonly int ProjectFunding = 3;
        public static readonly int TotalEmployee = 4;
        public static readonly int NumberOfServers = 5;
        public static readonly int TopBusinessConcern = 6;
    }
    

    Obviously, some of the enum type functionality will be lost, but for storing a bunch of database id constants, it seems like a pretty tidy solution.

    0 讨论(0)
提交回复
热议问题