8

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

我想测试一下是下雨还是雷暴(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,发票未支付原因等......)。

我也不想这样做:(这将删除为多人配置的能力)

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

6 回答 6

18

您当前的代码将说明它是否完全是“下雨和打雷”。要确定它是否“下雨、打雷以及可能是其他什么”,您需要:

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

要确定是“下雨还是打雷,可能还有其他”,您需要:

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

编辑(为了完整性):

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

还值得思考“阳光”的真正含义。它目前的值为 0,这意味着它没有其他所有内容;你不能同时晴天和下雨(当然,这在物理上是可能的)。请不要编写禁止彩虹的代码!;) 另一方面,如果在你的真实用例中你真的想要一个值,这意味着“没有所有其他值”,那么你很好。

于 2008-10-02T20:35:14.750 回答
2

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

  • 温度
  • 下雨多少
  • 抗风强度
  • 您喜欢的任何其他输入(例如雷暴)

然后,您可以使用算法来确定条件是否足够好。

我认为您还应该对骑自行车回家的天气保持不变的可能性有多大的投入。标准可能不同——回家后可以更轻松地淋浴和换衣服。

如果您真的想让它变得有趣,请从天气服务 api 收集输入数据,并每天评估决定 - 是的,我应该骑自行车,或者不,这是一个错误。然后也许你可以让应用程序学会做出更好的决定。

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

于 2011-11-09T15:36:34.983 回答
1

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

于 2008-10-02T20:31:39.907 回答
0

您需要在枚举上使用 [Flags] 属性(在此处查看);然后您可以使用按位并检查单个匹配项。

于 2008-10-02T20:35:41.457 回答
0

您应该在枚举上使用 Flags 属性。除此之外,您还需要测试是否设置了特定标志:

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

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

于 2008-10-02T20:37:39.033 回答
0

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

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

        if (Array.IndexOf(badWeatherTypes, currentWeather.Type) >= 0)
        {
                        return false;
        }
于 2008-10-02T21:01:48.493 回答