确定枚举值是否在列表中(C#)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/164425/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Determining if enum value is in list (C#)
提问by Nathan Koop
I am building a fun little app to determine if I should bike to work.
我正在构建一个有趣的小应用程序来确定我是否应该骑自行车上班。
I would like to test to see if it is either Raining or Thunderstorm(ing).
我想测试一下是下雨还是雷暴(ing)。
public enum WeatherType : byte
{ Sunny = 0, Cloudy = 1, Thunderstorm = 2, Raining = 4, Snowing = 8, MostlyCloudy = 16 }
I was thinking I could do something like:
我在想我可以做这样的事情:
WeatherType _badWeatherTypes = WeatherType.Thunderstorm | WeatherType.Raining;
if(currentWeather.Type == _badWeatherTypes)
{
return false;//don't bike
}
but this doesn't work because _badWeatherTypes is a combination of both types. I would like to keep them separated out because this is supposed to be a learning experience and having it separate may be useful in other situations (IE, Invoice not paid reason's etc...).
但这不起作用,因为 _badWeatherTypes 是两种类型的组合。我想将它们分开,因为这应该是一种学习体验,并且将其分开可能在其他情况下有用(IE、发票未付款原因等......)。
I would also rather not do: (this would remove the ability to be configured for multiple people)
我也宁愿不这样做:(这将取消为多人配置的能力)
if(WeatherType.Thunderstorm)
{
return false; //don't bike
}
etc...
采纳答案by Jon Skeet
Your current code will say whether it's exactly"raining and thundery". To find out whether it's "raining and thundery and possibly something else" you need:
您当前的代码将说明它是否完全是“下雨和打雷”。要确定是否“下雨和打雷,可能还有其他原因”,您需要:
if ((currentWeather.Type & _badWeatherTypes) == _badWeatherTypes)
To find out whether it's "raining orthundery, and possibly something else" you need:
要确定是“下雨还是打雷,以及可能还有其他原因”,您需要:
if ((currentWeather.Type & _badWeatherTypes) != 0)
EDIT (for completeness):
编辑(为了完整性):
It would be good to use the FlagsAttribute
, i.e. decorate the type with [Flags]
. This is not necessary for the sake of this bitwise logic, but affects how ToString()
behaves. The C# compiler ignores this attribute (at least at the moment; the C# 3.0 spec doesn't mention it) but it's generally a good idea for enums which are effectively flags, and it documents the intended use of the type. At the same time, the convention is that when you use flags, you pluralise the enum name - so you'd change it to WeatherTypes
(because any actual value is effectively 0 or more weather types).
最好使用FlagsAttribute
,即用 装饰类型[Flags]
。对于这种按位逻辑,这不是必需的,但会影响ToString()
行为方式。C# 编译器会忽略这个属性(至少目前是这样;C# 3.0 规范没有提到它)但是对于作为有效标志的枚举来说,这通常是一个好主意,并且它记录了类型的预期用途。同时,约定是当您使用标志时,您将枚举名称复数化 - 因此您将其更改为WeatherTypes
(因为任何实际值实际上是 0 或更多天气类型)。
It would also be worth thinking about what "Sunny" really means. It's currently got a value of 0, which means it's the absence of everything else; you couldn't have it sunny and raining at the same time (which is physically possible, of course). Please don't write code to prohibit rainbows! ;) On the other hand, if in your real use case you genuinely want a value which means "the absence of all other values" then you're fine.
也值得思考“Sunny”的真正含义。它当前的值为 0,这意味着它没有其他任何东西;你不能同时拥有晴天和下雨天(当然,这在物理上是可能的)。请不要写代码来禁止彩虹!;) 另一方面,如果在你的实际用例中你真的想要一个值,这意味着“没有所有其他值”那么你没问题。
回答by MagicKat
use the FlagsAttribute. That will allow you to use the enum as a bit mask.
使用 FlagsAttribute。这将允许您使用枚举作为位掩码。
回答by David Alpert
You need to use the [Flags] attribute (check here) on your enum; then you can use bitwise and to check for individual matches.
您需要在枚举上使用 [Flags] 属性(请在此处查看);然后您可以使用按位和检查单个匹配项。
回答by Scott Dorman
You should be using the Flags attribute on your enum. Beyond that, you also need to test to see if a particular flag is set by:
您应该在枚举上使用 Flags 属性。除此之外,您还需要测试是否通过以下方式设置了特定标志:
(currentWeather.Type & WeatherType.Thunderstorm == WeatherType.Thunderstorm)
This will test if currentWeather.Type has the WeatherType.Thunderstorm flag set.
这将测试 currentWeather.Type 是否设置了 WeatherType.Thunderstorm 标志。
回答by Ken Wootton
I wouldn't limit yourself to the bit world. Enums and bitwise operators are, as you found out, not the same thing. If you want to solve this using bitwise operators, I'd stick to just them, i.e. don't bother with enums. However, I'd something like the following:
我不会把自己局限在比特世界。正如您所发现的,枚举和按位运算符不是一回事。如果你想使用按位运算符解决这个问题,我会坚持只使用它们,即不要打扰枚举。但是,我想要以下内容:
WeatherType[] badWeatherTypes = new WeatherType[]
{
WeatherType.Thunderstorm,
WeatherType.Raining
};
if (Array.IndexOf(badWeatherTypes, currentWeather.Type) >= 0)
{
return false;
}
回答by LawrenceF
I'm not sure that it should be a flag - I think that you should have an range input for:
我不确定它应该是一个标志 - 我认为你应该有一个范围输入:
- Temperature
- How much it's raining
- Wind strength
- any other input you fancy (e.g. thunderstorm)
- 温度
- 下雨了多少
- 风力强度
- 您喜欢的任何其他输入(例如雷暴)
you can then use an algorithm to determine if the conditions are sufficiently good.
然后,您可以使用算法来确定条件是否足够好。
I think you should also have an input for how likely the weather is to remain the same for cycling home. The criteria may be different - you can shower and change more easliy when you get home.
我认为您还应该输入有关骑自行车回家的天气保持不变的可能性。标准可能会有所不同 - 您可以在回家后更轻松地淋浴和更换。
If you really want to make it interesting, collect the input data from a weather service api, and evaulate the decision each day - Yes, I should have cycled, or no, it was a mistake. Then perhaps you can have the app learn to make better decisions.
如果你真的想让它变得有趣,从天气服务 api 收集输入数据,并每天评估决定 - 是的,我应该循环,或者不,这是一个错误。那么也许您可以让应用程序学会做出更好的决定。
Next step is to "socialize" your decision, and see whether other people hear you are making the same decisions.
下一步是“社会化”你的决定,看看其他人是否听到你在做同样的决定。