我想要做的是这样的:我有枚举标记值的枚举.
public static class EnumExtension
{
public static bool IsSet<T>( this T input, T matchTo )
where T:enum //the constraint I want that doesn't exist in C#3
{
return (input & matchTo) != 0;
}
}
Run Code Online (Sandbox Code Playgroud)
那么我可以这样做:
MyEnum tester = MyEnum.FlagA | MyEnum.FlagB
if( tester.IsSet( MyEnum.FlagA ) )
//act on flag a
Run Code Online (Sandbox Code Playgroud)
不幸的是,C#的通用,其中约束没有枚举限制,只有类和结构.C#不会将枚举视为结构(即使它们是值类型),因此我无法像这样添加扩展类型.
有没有人知道解决方法?
我有很多固定大小的数字集合,其中每个条目都可以使用常量访问.当然,这似乎指向数组和枚举:
enum StatType {
Foo = 0,
Bar
// ...
}
float[] stats = new float[...];
stats[StatType.Foo] = 1.23f;
Run Code Online (Sandbox Code Playgroud)
这个问题当然是你不能使用枚举来索引没有强制转换的数组(虽然编译的IL使用普通的int).所以你必须在整个地方写这个:
stats[(int)StatType.foo] = 1.23f;
Run Code Online (Sandbox Code Playgroud)
我试图找到方法使用相同的简单语法而不进行强制转换但尚未找到完美的解决方案.使用字典似乎是不可能的,因为我发现它比数组慢大约320倍.我还尝试为枚举作为索引的数组编写泛型类:
public sealed class EnumArray<T>
{
private T[] array;
public EnumArray(int size)
{
array = new T[size];
}
// slow!
public T this[Enum idx]
{
get { return array[(int)(object)idx]; }
set { array[(int)(object)idx] = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
甚至是带有指定枚举的第二个通用参数的变体.这非常接近我想要的但问题是你不能只是将一个非特定的枚举(从泛型参数或盒装类型枚举)转换为int.相反,你必须首先使用强制转换为对象然后将其强制转换.这有效,但速度很慢.我发现为索引器生成的IL看起来像这样:
.method public hidebysig specialname instance !T get_Item(!E idx) cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: ldfld !0[] …Run Code Online (Sandbox Code Playgroud) 我想让int IDictionary<int, Driver>稍微不那么模糊它的含义,所以我想也许包装它会是一个好主意.结果将是这样的IDictionary<finishPosition, Driver>.
最好,finishPosition应该像这样分配finishPosition = 1.
我不知道这是否可行以及如何实现.