Using an enum as an array index in C#

前端 未结 10 952
死守一世寂寞
死守一世寂寞 2020-12-28 14:17

I want to do the same as in this question, that is:

enum DaysOfTheWeek {Sunday=0, Monday, Tuesday...};
string[] message_array = new string[number_of_items_at         


        
10条回答
  •  梦毁少年i
    2020-12-28 14:30

    If all you need is essentially a map, but don't want to incur performance overhead associated with dictionary lookups, this might work:

        public class EnumIndexedArray : IEnumerable> where TKey : struct
        {
            public EnumIndexedArray()
            {
                if (!typeof (TKey).IsEnum) throw new InvalidOperationException("Generic type argument is not an Enum");
                var size = Convert.ToInt32(Keys.Max()) + 1;
                Values = new T[size];
            }
    
            protected T[] Values;
    
            public static IEnumerable Keys
            {
                get { return Enum.GetValues(typeof (TKey)).OfType(); }
            }
    
            public T this[TKey index]
            {
                get { return Values[Convert.ToInt32(index)]; }
                set { Values[Convert.ToInt32(index)] = value; }
            }
    
            private IEnumerable> CreateEnumerable()
            {
                return Keys.Select(key => new KeyValuePair(key, Values[Convert.ToInt32(key)]));
            }
    
            public IEnumerator> GetEnumerator()
            {
                return CreateEnumerable().GetEnumerator();
            }
    
            IEnumerator IEnumerable.GetEnumerator()
            {
                return GetEnumerator();
            }
        }
    

    So in your case you could derive:

    class DaysOfWeekToStringsMap:EnumIndexedArray{};
    

    Usage:

    var map = new DaysOfWeekToStringsMap();
    
    //using the Keys static property
    foreach(var day in DaysOfWeekToStringsMap.Keys){
        map[day] = day.ToString();
    }
    foreach(var day in DaysOfWeekToStringsMap.Keys){
        Console.WriteLine("map[{0}]={1}",day, map[day]);
    }
    
    // using iterator
    foreach(var value in map){
        Console.WriteLine("map[{0}]={1}",value.Key, value.Value);
    }
    

    Obviously this implementation is backed by an array, so non-contiguous enums like this:

    enum
    {
      Ok = 1,
      NotOk = 1000000
    }
    

    would result in excessive memory usage.

    If you require maximum possible performance you might want to make it less generic and loose all generic enum handling code I had to use to get it to compile and work. I didn't benchmark this though, so maybe it's no big deal.

    Caching the Keys static property might also help.

提交回复
热议问题