C# で以下の様な、初期化して読み出すだけの enum の Dictionary を作りたい場合、通常の Dictionary はメモリ効率や処理速度の点で効率が悪いので、単純なものが欲しかったので考えてみました。
以下のような使い方が出来ればそれだけでいい。
enum EnumAlpha
{
A,
B,
}
Dictionary<EnumAlpha, StructAB> dic1 = new Dictionary<EnumAlpha, StructAB>()
{
{EnumAlpha.A, "A"},
{EnumAlpha.B, "B"}
};
enumだけをキーとして使うDictionaryクラス。
中はテーブルで、enum の個数分あらかじめ確保しています。
取り出しがめっちゃ速いはず。
ENumDictionay.cs
class ENumDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>> where TKey : struct, IConvertible
{
private TValue[] array = null;
public ENumDictionary()
{
int length = Enum.GetNames(typeof(TKey)).Length;
array = new TValue[length];
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return new MyEnumerator(this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public TValue this[TKey key]
{
set
{
array[KeyToIndex(key)] = value;
}
get
{
return array[KeyToIndex(key)];
}
}
private static int KeyToIndex(TKey key)
{
return (int)(object)key;
}
private static TKey IndexToKey(int index)
{
return (TKey)(object)index;
}
public TValue this[int i]
{
set { array[i] = value; }
get { return array[i]; }
}
class MyEnumerator : IEnumerator<KeyValuePair<TKey, TValue>>
{
private ENumDictionary<TKey, TValue> dictionary;
private int getIndex;
private KeyValuePair<TKey, TValue> currentValue;
public MyEnumerator(ENumDictionary<TKey, TValue> enumDictionary)
{
dictionary = enumDictionary;
getIndex = 0;
}
object IEnumerator.Current => currentValue;
KeyValuePair<TKey, TValue> IEnumerator<KeyValuePair<TKey, TValue>>.Current => currentValue;
public void Dispose()
{
}
public bool MoveNext()
{
if (getIndex >= dictionary.array.Length)
{
return false;
}
TKey key = IndexToKey(getIndex);
TValue value = dictionary.array[getIndex];
currentValue = new KeyValuePair<TKey, TValue>(key, value);
getIndex++;
return true;
}
public void Reset() { getIndex = 0; }
}
public void Add(TKey key, TValue v0)
{
array[KeyToIndex(key)] = v0;
}
}
テストコード
struct StructAB
{
public int a, b;
public StructAB(int a, int b)
{
this.a = a;
this.b = b;
}
public override string ToString()
{
return string.Format("{0},{1}", a, b);
}
}
private enum EnumAlpha
{
A,
B,
}
void Start()
{
ENumDictionary<EnumAlpha, string> dic0 = new ENumDictionary<EnumAlpha, string>()
{
{EnumAlpha.A, "A"},
{EnumAlpha.B, "B"}
};
foreach (var it in dic0)
{
Debug.Log(" " + it);
}
ENumDictionary<EnumAlpha, StructAB> dic1 = new ENumDictionary<EnumAlpha, StructAB>()
{
{EnumAlpha.A, new StructAB(12, 13)},
{EnumAlpha.B, new StructAB(14, 15)}
};
foreach (var it in dic1)
{
Debug.Log(" " + it.Value);
}
Debug.Log("A : " + dic1[EnumAlpha.A]);
Debug.Log("B : " + dic1[EnumAlpha.B]);
dic1[EnumAlpha.A] = new StructAB(21, 22);
Debug.Log("B : " + dic1[EnumAlpha.A]);
}
private static int KeyToIndex(TKey key)
private static TKey IndexToKey(int index)
以上の enum と int の変換ですが
Expression を駆使すると高速になるようです。
検索すると沢山でてきますよー
初めての投稿です。
間違ってたら教えてください~