是否有可能创建一个通用的按位枚举'IsOptionSet()'的方法? [英] Is it possible to create a generic bitwise enumeration 'IsOptionSet()' method?
问题描述
下面code可以很容易地在一组HtmlParserOptions传递,然后核对单选项,查看是否是被选中。
[国旗]
公共枚举HtmlParserOptions
{
NotifyOpeningTags = 1,
NotifyClosingTags = 2,
NotifyText = 4,
NotifyEmptyText = 8
}私人布尔IsOptionSet(HtmlParserOptions选项,HtmlParserOptions singleOption)
{
返回(选项和放大器; singleOption)== singleOption;
}
我的问题是,是有可能创造的这个通用版本(我猜通过实施的方法属性的接口),将一起工作的任何的枚举的标志属性<? / p>
编辑:
最简单,最好的选择是升级到Beta2的VS2010和使用.NET 4的的 Enum.HasFlag 方法。该框架团队已经增加了很多很好的补充,以枚举,使他们更好的使用。
原件(当前.NET):
您可以通过传递枚举,而不是泛型做到这一点:
静态类EnumExtensions
{
私人静态布尔IsSignedType code(类型code code)
{
开关(code)
{
案件类型code.Byte:
案件类型code.UInt16:
案件类型code.UInt32:
案件类型code.UInt64:
返回false;
默认:
返回true;
}
} 公共静态布尔IsOptionSet(此枚举值,枚举选项)
{
如果(IsSignedType code(value.GetType code()))
{
长longVal = Convert.ToInt64(值);
长longOpt = Convert.ToInt64(选件);
返回(longVal&安培; longOpt)== longOpt;
}
其他
{
ULONG longVal = Convert.ToUInt64(值);
ULONG longOpt = Convert.ToUInt64(选件);
返回(longVal&安培; longOpt)== longOpt;
}
}
}
这完美的作品,像这样:
类节目
{
静态无效的主要(字串[] args)
{
HtmlParserOptions OPT1 = HtmlParserOptions.NotifyText | HtmlParserOptions.NotifyEmptyText;
Console.WriteLine(文字:{0},opt1.IsOptionSet(HtmlParserOptions.NotifyText));
Console.WriteLine(OpeningTags:{0},opt1.IsOptionSet(HtmlParserOptions.NotifyOpeningTags)); Console.ReadKey();
}
}
上面打印:
真: 正文
OpeningTags:假
这样做的缺点,虽然,它不能保护你免受通过两种不同类型的枚举类型的进入程序。你必须合理地使用它。
The below code makes it easy to pass in a set HtmlParserOptions and then check against a single option to see if it's been selected.
[Flags]
public enum HtmlParserOptions
{
NotifyOpeningTags = 1,
NotifyClosingTags = 2,
NotifyText = 4,
NotifyEmptyText = 8
}
private bool IsOptionSet(HtmlParserOptions options, HtmlParserOptions singleOption)
{
return (options & singleOption) == singleOption;
}
My question is, is it possible to create a Generic version of this (I'm guessing through implementing an interface on the method properties) that will work with any enumeration with the Flags attribute?
Edit:
The easiest, nicest option is to upgrade to VS2010 Beta2 and use .NET 4's Enum.HasFlag method. The framework team has added a lot of nice additions to Enum to make them nicer to use.
Original (for current .NET):
You can do this by passing Enum, instead of generics:
static class EnumExtensions
{
private static bool IsSignedTypeCode(TypeCode code)
{
switch (code)
{
case TypeCode.Byte:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
return false;
default:
return true;
}
}
public static bool IsOptionSet(this Enum value, Enum option)
{
if (IsSignedTypeCode(value.GetTypeCode()))
{
long longVal = Convert.ToInt64(value);
long longOpt = Convert.ToInt64(option);
return (longVal & longOpt) == longOpt;
}
else
{
ulong longVal = Convert.ToUInt64(value);
ulong longOpt = Convert.ToUInt64(option);
return (longVal & longOpt) == longOpt;
}
}
}
This works perfectly, like so:
class Program
{
static void Main(string[] args)
{
HtmlParserOptions opt1 = HtmlParserOptions.NotifyText | HtmlParserOptions.NotifyEmptyText;
Console.WriteLine("Text: {0}", opt1.IsOptionSet(HtmlParserOptions.NotifyText));
Console.WriteLine("OpeningTags: {0}", opt1.IsOptionSet(HtmlParserOptions.NotifyOpeningTags));
Console.ReadKey();
}
}
THe above prints:
Text: True
OpeningTags: False
The downside to this, though, is it doesn't protect you from passing two different types of Enum types into the routine. You have to use it reasonably.
这篇关于是否有可能创建一个通用的按位枚举'IsOptionSet()'的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!