Определение, находится ли значение перечисления в списке (C #) - PullRequest
8 голосов
/ 03 октября 2008

Я создаю забавное маленькое приложение, чтобы определить, должен ли я ездить на велосипеде на работу.

Я бы хотел проверить, идет ли дождь или гроза (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 является комбинацией обоих типов. Я хотел бы, чтобы они были отделены друг от друга, потому что это должен быть учебный опыт, и его разделение может быть полезным в других ситуациях (например, счет, неоплаченная причина и т. Д.)

Я бы тоже предпочел не делать: (это исключило бы возможность настройки для нескольких человек)

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

Ответы [ 6 ]

18 голосов
/ 03 октября 2008

Ваш текущий код скажет, будет ли точно"дождь и гроза". Чтобы узнать, идет ли «дождь и гроза и, возможно, что-то еще», вам нужно:

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

Чтобы узнать, идет ли "дождь или гроза, и, возможно, что-то еще", вам нужно:

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

РЕДАКТИРОВАТЬ (для полноты):

Было бы хорошо использовать FlagsAttribute, то есть украсить тип с помощью [Flags]. Это необязательно ради побитовой логики, но влияет на поведение ToString(). Компилятор C # игнорирует этот атрибут (по крайней мере, на данный момент; спецификация C # 3.0 не упоминает его), но это, как правило, хорошая идея для перечислений, которые фактически являются флагами, и он документирует предполагаемое использование типа. В то же время, соглашение заключается в том, что когда вы используете флаги, вы вводите имя enum в множественном числе, поэтому вы меняете его на WeatherTypes (потому что любое действительное значение фактически равно 0 или более типов погоды).

Также стоит подумать о том, что на самом деле означает "Солнечный". В настоящее время он имеет значение 0, что означает отсутствие всего остального; Вы не могли бы иметь солнечную погоду и дождь одновременно (что, конечно, физически возможно). Пожалуйста, не пишите код, запрещающий радугу! ;) С другой стороны, если в вашем реальном случае использования вы действительно хотите значение, которое означает «отсутствие всех других значений», то все в порядке.

2 голосов
/ 09 ноября 2011

Я не уверен, что это должен быть флаг - я думаю, что вы должны иметь диапазон ввода для:

  • Температура
  • Сколько идет дождь
  • Сила ветра
  • любой другой интересующий вас ввод (например, гроза)

Затем вы можете использовать алгоритм, чтобы определить, достаточно ли хороши условия.

Я думаю, вы должны также указать, насколько вероятно, что погода останется неизменной для езды на велосипеде. Критерии могут быть разными - вы можете принять душ и поменять больше, когда вернетесь домой.

Если вы действительно хотите, чтобы это было интересно, собирайте входные данные из API службы погоды и анализируйте решение каждый день - да, я должен был ездить на велосипеде, или нет, это была ошибка. Тогда, возможно, вы сможете научить приложение принимать правильные решения.

Следующий шаг - «социализировать» ваше решение и посмотреть, слышат ли другие люди, что вы принимаете те же решения.

1 голос
/ 03 октября 2008

используйте атрибут FlagsAttribute. Это позволит вам использовать перечисление в качестве битовой маски.

0 голосов
/ 03 октября 2008

Я бы не ограничивал себя битым миром. Перечисления и побитовые операторы, как вы выяснили, не одно и то же. Если вы хотите решить эту проблему с помощью побитовых операторов, я бы придерживался только их, то есть не беспокоиться о перечислениях. Тем не менее, я хотел бы что-то вроде следующего:

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

        if (Array.IndexOf(badWeatherTypes, currentWeather.Type) >= 0)
        {
                        return false;
        }
0 голосов
/ 03 октября 2008

Вы должны использовать атрибут Flags в вашем перечислении. Кроме того, вам также нужно проверить, установлен ли определенный флаг:

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

Это проверит, установлен ли флаг currentWeather.Type в WeatherType.Thunderstorm.

0 голосов
/ 03 октября 2008

Вам необходимо использовать атрибут [Flags] ( отметьте здесь ) в вашем перечислении; затем вы можете использовать побитовое и для проверки на индивидуальные совпадения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...