String representation of an Enum

后端 未结 30 1933
不思量自难忘°
不思量自难忘° 2020-11-22 02:44

I have the following enumeration:

public enum AuthenticationMethod
{
    FORMS = 1,
    WINDOWSAUTHENTICATION = 2,
    SINGLESIGNON = 3
}

T

30条回答
  •  爱一瞬间的悲伤
    2020-11-22 03:04

    A lot of great answers here but in my case did not solve what I wanted out of an "string enum", which was:

    1. Usable in a switch statement e.g switch(myEnum)
    2. Can be used in function parameters e.g. foo(myEnum type)
    3. Can be referenced e.g. myEnum.FirstElement
    4. I can use strings e.g. foo("FirstElement") == foo(myEnum.FirstElement)

    1,2 & 4 can actually be solved with a C# Typedef of a string (since strings are switchable in c#)

    3 can be solved by static const strings. So if you have the same needs, this is the simplest approach:

    public sealed class Types
    {
    
        private readonly String name;
    
        private Types(String name)
        {
            this.name = name;
    
        }
    
        public override String ToString()
        {
            return name;
        }
    
        public static implicit operator Types(string str)
        {
            return new Types(str);
    
        }
        public static implicit operator string(Types str)
        {
            return str.ToString();
        }
    
    
        #region enum
    
        public const string DataType = "Data";
        public const string ImageType = "Image";
        public const string Folder = "Folder";
        #endregion
    
    }
    

    This allows for example:

        public TypeArgs(Types SelectedType)
        {
            Types SelectedType = SelectedType
        }
    

    and

    public TypeObject CreateType(Types type)
        {
            switch (type)
            {
    
                case Types.ImageType:
                  //
                    break;
    
                case Types.DataType:
                 //
                    break;
    
            }
        }
    

    Where CreateType can be called with a string or a type. However the downside is that any string is automatically a valid enum, this could be modified but then it would require some kind of init function...or possibly make they explicit cast internal?

    Now if an int value was important to you (perhaps for comparison speed), you could use some ideas from Jakub Šturc fantastic answer and do something a bit crazy, this is my stab at it:

        public sealed class Types
    {
        private static readonly Dictionary strInstance = new Dictionary();
        private static readonly Dictionary intInstance = new Dictionary();
    
        private readonly String name;
        private static int layerTypeCount = 0;
        private int value;
        private Types(String name)
        {
            this.name = name;
            value = layerTypeCount++;
            strInstance[name] = this;
            intInstance[value] = this;
        }
    
        public override String ToString()
        {
            return name;
        }
    
    
        public static implicit operator Types(int val)
        {
            Types result;
            if (intInstance.TryGetValue(val, out result))
                return result;
            else
                throw new InvalidCastException();
        }
    
        public static implicit operator Types(string str)
        {
            Types result;
            if (strInstance.TryGetValue(str, out result))
            {
                return result;
            }
            else
            {
                result = new Types(str);
                return result;
            }
    
        }
        public static implicit operator string(Types str)
        {
            return str.ToString();
        }
    
        public static bool operator ==(Types a, Types b)
        {
            return a.value == b.value;
        }
        public static bool operator !=(Types a, Types b)
        {
            return a.value != b.value;
        }
    
        #region enum
    
        public const string DataType = "Data";
        public const string ImageType = "Image";
    
        #endregion
    
    }
    

    but of course "Types bob = 4;" would be meaningless unless you had initialized them first which would sort of defeat the point...

    But in theory TypeA == TypeB would be quicker...

提交回复
热议问题