确定枚举值是否在列表中(C#)

时间:2008-10-02 20:29:50

标签: c# .net enums

我正在构建一个有趣的小应用程序来确定我是否应该自行上班。

我想测试一下是下雨还是雷雨(ing)。

public enum WeatherType : byte
{ Sunny = 0, Cloudy = 1, Thunderstorm = 2, Raining = 4, Snowing = 8, MostlyCloudy = 16 }

我以为我可以这样做:

WeatherType _badWeatherTypes = WeatherType.Thunderstorm | WeatherType.Raining;
if(currentWeather.Type == _badWeatherTypes)
{
 return false;//don't bike
}

但这不起作用,因为_badWeatherTypes是两种类型的组合。我想将它们分开,因为这应该是一种学习经验,并且将它分开可能在其他情况下有用(IE,Invoice not paid reason's etc ...)。

我也不愿意这样做:(这会删除为多人配置的能力)

if(WeatherType.Thunderstorm)
{
 return false; //don't bike
}
etc...

6 个答案:

答案 0 :(得分:18)

您当前的代码会说明完全是“下雨和雷雨”。要了解它是否需要“下雨和雷雨以及其他可能的东西”:

if ((currentWeather.Type & _badWeatherTypes) == _badWeatherTypes)

要确定是否需要“下雨雷声,可能还有其他事情”:

if ((currentWeather.Type & _badWeatherTypes) != 0)

编辑(完整性):

最好使用FlagsAttribute,即用[Flags]修饰类型。对于这种按位逻辑,这不是必需的,但会影响ToString()的行为。 C#编译器忽略了这个属性(至少在目前; C#3.0规范没有提到它),但对于有效标记的枚举通常是一个好主意,它记录了该类型的预期用途。同时,惯例是当你使用标志时,你将枚举名称复数 - 所以你要将它改为WeatherTypes(因为任何实际值实际上都是0或更多天气类型)。

值得思考“Sunny”究竟意味着什么。它目前的值为0,这意味着它缺少其他一切;你不能在阳光下和同时下雨(当然这在身体上是可能的)。请不要编写代码来禁止彩虹! ;)另一方面,如果在您的真实用例中,您真正想要一个意味着“缺少所有其他值”的值,那么您就可以了。

答案 1 :(得分:2)

我不确定它应该是一个标志 - 我认为你应该有一个范围输入:

  • 温度
  • 下雨了多少
  • 风力
  • 您喜欢的任何其他输入(例如雷暴)
然后,您可以使用算法来确定条件是否足够好。

我认为您还应该了解自行车回家的天气状况。标准可能有所不同 - 当你回家时,你可以淋浴并且更容易改变。

如果你真的想让它变得有趣,那就从天气服务api收集输入数据,并每天评估决定 - 是的,我应该循环,或者不是,这是一个错误。那么也许你可以让应用学习做出更好的决定。

下一步是将您的决定“社交化”,看看其他人是否听到您做出同样的决定。

答案 2 :(得分:1)

使用FlagsAttribute。这将允许您使用枚举作为位掩码。

答案 3 :(得分:0)

您需要在枚举上使用[Flags]属性(check here);然后你可以使用按位并检查个别匹配。

答案 4 :(得分:0)

您应该在枚举上使用Flags属性。除此之外,您还需要测试以查看是否通过以下方式设置特定标志:

(currentWeather.Type & WeatherType.Thunderstorm == WeatherType.Thunderstorm)

这将测试currentWeather.Type是否设置了WeatherType.Thunderstorm标志。

答案 5 :(得分:0)

我不会把自己限制在比特世界。正如您所发现的,枚举和按位运算符不是一回事。如果你想使用按位运算符解决这个问题,我会坚持使用它们,即不要打扰枚举。但是,我有以下几点:

        WeatherType[] badWeatherTypes = new WeatherType[]
        {   
            WeatherType.Thunderstorm, 
            WeatherType.Raining
        };

        if (Array.IndexOf(badWeatherTypes, currentWeather.Type) >= 0)
        {
                        return false;
        }