Nef*_*zen 27 c# indexing enums
我想在这个问题上做同样的事情,那就是:
enum DaysOfTheWeek {Sunday=0, Monday, Tuesday...};
string[] message_array = new string[number_of_items_at_enum];
...
Console.Write(custom_array[(int)DaysOfTheWeek.Sunday]);
Run Code Online (Sandbox Code Playgroud)
但是,我宁愿有一些不可或缺的东西,而不是写这个容易出错的代码.C#中是否有内置模块可以做到这一点?
Meh*_*ari 18
如果枚举项的值是有余的,则数组方法可以很好地工作.但是,在任何情况下,您都可以使用Dictionary<DayOfTheWeek, string>(顺便说一下,性能较差).
Ian*_*dby 10
从 C# 7.3 开始,可以将其System.Enum用作类型参数的约束。因此,不再需要其他一些答案中令人讨厌的黑客攻击。
这是一个非常简单的ArrayByEum类,它完全满足了问题的要求。
请注意,如果枚举值不连续,它将浪费空间,并且不会处理对于int. 我确实说过这个例子非常简单。
/// <summary>An array indexed by an Enum</summary>
/// <typeparam name="T">Type stored in array</typeparam>
/// <typeparam name="U">Indexer Enum type</typeparam>
public class ArrayByEnum<T,U> : IEnumerable where U : Enum // requires C# 7.3 or later
{
private readonly T[] _array;
private readonly int _lower;
public ArrayByEnum()
{
_lower = Convert.ToInt32(Enum.GetValues(typeof(U)).Cast<U>().Min());
int upper = Convert.ToInt32(Enum.GetValues(typeof(U)).Cast<U>().Max());
_array = new T[1 + upper - _lower];
}
public T this[U key]
{
get { return _array[Convert.ToInt32(key) - _lower]; }
set { _array[Convert.ToInt32(key) - _lower] = value; }
}
public IEnumerator GetEnumerator()
{
return Enum.GetValues(typeof(U)).Cast<U>().Select(i => this[i]).GetEnumerator();
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
ArrayByEnum<string,MyEnum> myArray = new ArrayByEnum<string,MyEnum>();
myArray[MyEnum.First] = "Hello";
myArray[YourEnum.Other] = "World"; // compiler error
Run Code Online (Sandbox Code Playgroud)
你可以创建一个可以为你工作的类或结构
public class Caster
{
public enum DayOfWeek
{
Sunday = 0,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
public Caster() {}
public Caster(string[] data) { this.Data = data; }
public string this[DayOfWeek dow]{
get { return this.Data[(int)dow]; }
}
public string[] Data { get; set; }
public static implicit operator string[](Caster caster) { return caster.Data; }
public static implicit operator Caster(string[] data) { return new Caster(data); }
}
class Program
{
static void Main(string[] args)
{
Caster message_array = new string[7];
Console.Write(message_array[Caster.DayOfWeek.Sunday]);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑
由于缺乏更好的地方,我在下面发布了Caster类的通用版本.不幸的是,它依赖于运行时检查来强制执行TKey作为枚举.
public enum DayOfWeek
{
Weekend,
Sunday = 0,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
public class TypeNotSupportedException : ApplicationException
{
public TypeNotSupportedException(Type type)
: base(string.Format("The type \"{0}\" is not supported in this context.", type.Name))
{
}
}
public class CannotBeIndexerException : ApplicationException
{
public CannotBeIndexerException(Type enumUnderlyingType, Type indexerType)
: base(
string.Format("The base type of the enum (\"{0}\") cannot be safely cast to \"{1}\".",
enumUnderlyingType.Name, indexerType)
)
{
}
}
public class Caster<TKey, TValue>
{
private readonly Type baseEnumType;
public Caster()
{
baseEnumType = typeof(TKey);
if (!baseEnumType.IsEnum)
throw new TypeNotSupportedException(baseEnumType);
}
public Caster(TValue[] data)
: this()
{
Data = data;
}
public TValue this[TKey key]
{
get
{
var enumUnderlyingType = Enum.GetUnderlyingType(baseEnumType);
var intType = typeof(int);
if (!enumUnderlyingType.IsAssignableFrom(intType))
throw new CannotBeIndexerException(enumUnderlyingType, intType);
var index = (int) Enum.Parse(baseEnumType, key.ToString());
return Data[index];
}
}
public TValue[] Data { get; set; }
public static implicit operator TValue[](Caster<TKey, TValue> caster)
{
return caster.Data;
}
public static implicit operator Caster<TKey, TValue>(TValue[] data)
{
return new Caster<TKey, TValue>(data);
}
}
// declaring and using it.
Caster<DayOfWeek, string> messageArray =
new[]
{
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
};
Console.WriteLine(messageArray[DayOfWeek.Sunday]);
Console.WriteLine(messageArray[DayOfWeek.Monday]);
Console.WriteLine(messageArray[DayOfWeek.Tuesday]);
Console.WriteLine(messageArray[DayOfWeek.Wednesday]);
Console.WriteLine(messageArray[DayOfWeek.Thursday]);
Console.WriteLine(messageArray[DayOfWeek.Friday]);
Console.WriteLine(messageArray[DayOfWeek.Saturday]);
Run Code Online (Sandbox Code Playgroud)
干得好:
string[] message_array = Enum.GetNames(typeof(DaysOfTheWeek));
Run Code Online (Sandbox Code Playgroud)
如果您确实需要长度,那么只需在结果上取 .Length :) 您可以通过以下方式获取值:
string[] message_array = Enum.GetValues(typeof(DaysOfTheWeek));
Run Code Online (Sandbox Code Playgroud)
用作索引并将任何类型分配给字典和强类型的枚举的紧凑形式。在这种情况下,返回浮点值,但值可能是具有属性和方法等的复杂类实例:
enum opacityLevel { Min, Default, Max }
private static readonly Dictionary<opacityLevel, float> _oLevels = new Dictionary<opacityLevel, float>
{
{ opacityLevel.Max, 40.0 },
{ opacityLevel.Default, 50.0 },
{ opacityLevel.Min, 100.0 }
};
//Access float value like this
var x = _oLevels[opacitylevel.Default];
Run Code Online (Sandbox Code Playgroud)