任何人都知道缺乏枚举通用约束的一个很好的解决方法?
我想要做的是这样的:我已经枚举了带标记值的组合。
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;
}
}
那么我可以这样做:
MyEnum tester = MyEnum.FlagA | MyEnum.FlagB
if( tester.IsSet( MyEnum.FlagA ) )
//act on flag a
不幸的是C#的泛型约束没有枚举限制,只有类和结构。 C#没有将枚举看成结构体(即使它们是值类型),所以我不能像这样添加扩展类型。
任何人都知道解决方法?
编辑:这是现在生活在UnconstrainedMelody版本0.0.0.2。
(正如我在博客上发布的关于枚举约束的文章所要求的,为了独立的答案,我已经包含了下面的基本事实。)
最好的解决办法是等待我将它包含在UnconstrainedMelody1中。 这是一个使C#代码具有“假”约束的库,如
where T : struct, IEnumConstraint
并把它变成
where T : struct, System.Enum
通过后建设步骤。
编写IsSet
应该不会太难......尽管兼顾基于Int64
和基于UInt64
的标志可能是棘手的部分。 (我嗅到了一些帮助器方法,基本上允许我将任何标志枚举视为具有基本类型的UInt64
。)
如果你打电话,你想要什么样的行为
tester.IsSet(MyFlags.A | MyFlags.C)
? 是否应检查是否设置了所有指定的标志? 那将是我的期望。
我会在今晚回家的路上尝试做这件事......我希望能快速闪现有用的枚举方法,以便让库快速达到可用标准,然后放松一下。
编辑:顺便说一句,我不确定IsSet
是一个名字。 选项:
思想欢迎。 无论如何,我相信这将会是一段时间,然而任何事情都是石头而已。
1或将其作为补丁提交,当然...
Darren,如果这些类型是特定的枚举,那么这将起作用 - 对于一般的枚举工作,您必须将它们转换为整数(或更可能是uint)来执行布尔运算:
public static bool IsSet( this Enum input, Enum matchTo )
{
return ( Convert.ToUInt32( input ) & Convert.ToUInt32( matchTo ) ) != 0;
}
事实上,这是可能的,一个丑陋的伎俩。 但是,它不能用于扩展方法。
public abstract class Enums<Temp> where Temp : class {
public static TEnum Parse<TEnum>(string name) where TEnum : struct, Temp {
return (TEnum)Enum.Parse(typeof(TEnum), name);
}
}
public abstract class Enums : Enums<Enum> { }
Enums.IsSet<DateTimeKind>("Local")
如果你愿意,你可以给Enums<Temp>
一个私有构造函数和一个公共嵌套抽象继承类, Temp
为Enum
,以防止非枚举的继承版本。
上一篇: Anyone know a good workaround for the lack of an enum generic constraint?