I am facing problem when I am trying to create dictionary, where key is System.Enum. Problem is, that dictionary like this allocates garbage because default EqualityComparer is not one of the best. I tryed to write my own comparer, but without any success. Is it somehow possible?
public enum MyEnum
{
One, Two, Three
}
public Dictionary<Enum, string> dict = new Dictionary<Enum, string>();
public void Test()
{
this.dict.Add(MyEnum.One, "One");
this.dict.Add(MyEnum.Two, "Two");
this.dict.Add(MyEnum.Three, "Three");
string result;
this.dict.TryGetValue(MyEnum.Two, out result); // <-- memory alocation :-(
}
Seeing your example in the comments, and that this is for Unity, watch this clip from Unite 2016. It talks about using Scriptable Objects instead of enums for dictionary keys.
What you would do is have
public class Program
{
protected Dictionary<ScriptableObject, string> dict = new Dictionary<ScriptableObject, string>();
}
public class ProgramChild1 : Program
{
public void Test()
{
dict.Add(MyEnum1.One.Instance, "One");
dict.Add(MyEnum1.Two.Instance, "Two");
dict.Add(MyEnum1.Three.Instance, "Three");
string result;
dict.TryGetValue(MyEnum1.Two.Instance, out result);
}
}
public class ProgramChild2 : Program
{
public void Test()
{
dict.Add(MyEnum2.Four.Instance, "One");
dict.Add(MyEnum2.Five.Instance, "Two");
dict.Add(MyEnum2.Six.Instance, "Three");
string result;
dict.TryGetValue(MyEnum2.Five.Instance, out result);
}
}
//Each class goes in to its own .cs file, Put them in two folders `MyEnum1` and `MyEnum2`
namespace MyEnum1
{
public class One : ScriptableObject
{
private static One _inst;
public static One Instance
{
get
{
if (!_inst)
_inst = Resources.FindObjectOfType<One>();
if (!_inst)
_inst = CreateInstance<One>();
return _inst;
}
}
}
}
namespace MyEnum1
{
public class Two : ScriptableObject
{
private static Two _inst;
public static Two Instance
{
get
{
if (!_inst)
_inst = Resources.FindObjectOfType<Two>();
if (!_inst)
_inst = CreateInstance<Two>();
return _inst;
}
}
}
}
namespace MyEnum1
{
public class Three : ScriptableObject
{
private static Three _inst;
public static Three Instance
{
get
{
if (!_inst)
_inst = Resources.FindObjectOfType<Three>();
if (!_inst)
_inst = CreateInstance<Three>();
return _inst;
}
}
}
}
namespace MyEnum2
{
public class Four : ScriptableObject
{
private static Four_inst;
public static Four Instance
{
get
{
if (!_inst)
_inst = Resources.FindObjectOfType<Four>();
if (!_inst)
_inst = CreateInstance<Four>();
return _inst;
}
}
}
}
namespace MyEnum2
{
public class Five : ScriptableObject
{
private static Five _inst;
public static Five Instance
{
get
{
if (!_inst)
_inst = Resources.FindObjectOfType<Five>();
if (!_inst)
_inst = CreateInstance<Five>();
return _inst;
}
}
}
}
namespace MyEnum2
{
public class Six : ScriptableObject
{
private static Six _inst;
public static Six Instance
{
get
{
if (!_inst)
_inst = Resources.FindObjectOfType<Six>();
if (!_inst)
_inst = CreateInstance<Six>();
return _inst;
}
}
}
}
Note that the reason we inherit from ScriptableObject
is if you wanted to expose a enum to the designer you could then drag and drop the enum value right in the designer, you could not do this if the enums where just basic classes.
public class ProgramChild2 : Program
{
public ScriptableObject SelectedValue;
public void Test()
{
dict.Add(MyEnum2.Four.Instance, "One");
dict.Add(MyEnum2.Five.Instance, "Two");
dict.Add(MyEnum2.Six.Instance, "Three");
string result;
dict.TryGetValue(SelectedValue, out result);
}
}