2008-10-02 11 views
8

Buduję zabawną małą aplikację, aby określić, czy powinienem jeździć na rowerze do pracy.Określanie, czy wartość wyliczenia znajduje się na liście (C#)

Chciałbym przetestować, czy jest to Raining lub burza (ing).

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

Myślałam mógłby zrobić coś takiego:

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

ale to nie działa, ponieważ _badWeatherTypes to połączenie obu typów. Chciałbym je oddzielić, ponieważ ma to być doświadczenie edukacyjne, a oddzielenie go może być przydatne w innych sytuacjach (np. Faktury, nieumyślne przyczyny itp.).

Chciałbym też raczej nie (to usunie możliwość być skonfigurowany dla wielu osób)

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

Odpowiedz

18

Twój obecny kod mówi, czy jest to dokładnie "pada deszcz i thundery". Aby dowiedzieć się, czy to „deszcz i thundery i ewentualnie coś else” potrzebujesz:

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

aby dowiedzieć się, czy jest to „pada lub thundery i ewentualnie coś else” potrzebujesz:

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

EDYCJA (dla kompletności):

Byłoby dobrze użyć FlagsAttribute, tj. Udekorować typ przy pomocy [Flags]. Nie jest to konieczne ze względu na tę logikę bitową, ale ma wpływ na zachowanie ToString(). Kompilator C# ignoruje ten atrybut (przynajmniej w tej chwili, specyfikacja C# 3.0 nie wspomina o tym), ale ogólnie jest dobry pomysł na wyliczenia, które są efektywnymi flagami i dokumentuje zamierzone użycie typu. W tym samym czasie konwencja jest taka, że ​​gdy używasz flag, zmieniasz nazwę enum - tak byś zmienił ją na WeatherTypes (ponieważ każda rzeczywista wartość to 0 lub więcej typów pogody).

Warto również pomyśleć o tym, co naprawdę znaczy "Słoneczny". Obecnie ma wartość 0, co oznacza, że ​​jest to brak wszystkiego; nie można było tego robić jednocześnie słonecznie i pada (oczywiście jest to fizycznie możliwe). Proszę nie pisać kodu, aby zabronić tęczy! ;) Z drugiej strony, jeśli w twoim prawdziwym przypadku naprawdę chcesz wartości, co oznacza "brak wszystkich innych wartości", wszystko jest w porządku.

+0

[Flagi] wydaje się być sposobem, aby przejść tutaj. –

+0

Cóż, zdecydowanie jest to dobre - ale jest to całkowicie ortogonalne w stosunku do faktycznego pytania. Nie pomoże ani nie utrudni logiki bitowej. –

+0

Miałeś rację co do "Sunny", musiałem to zmienić. Dziękuję wszystkim za pomoc. –

1

korzystania z FlagsAttribute. To pozwoli ci użyć wyliczenia jako maski bitowej.

+0

Możesz użyć wyliczenia jako maski bitowej bez flag; FlagsAttribute po prostu zmienia sposób działania ToString. Mimo to dobrym pomysłem byłoby włączenie go do tego. –

+0

To po prostu zmienia sposób działania ToString, ale nie ma gwarancji, że przyszłe wersje .NET nie zmienią innych zachowań (jak kompilator generujący błędy, jeśli wartości nie są potęgami 2), więc powinieneś zawsze używać go podczas używania wyliczenie flag. –

+0

Ah, nie wiedziałem, że to po prostu zmieniło ToString(). Ciekawy. – MagicKat

0

Musisz użyć atrybutu [Flagi] (check here) w swoim wyliczeniu; możesz użyć bitowego i sprawdzić poszczególne mecze.

+0

Proszę zobaczyć moją odpowiedź na MagicKat. Flagi są pożądane, ale nie są tu konieczne. –

0

Powinieneś używać atrybutu Flags w swoim wyliczeniu. Poza tym, należy również sprawdzać, czy dana flaga jest ustawiona przez:

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

będzie to sprawdzić, czy currentWeather.Type ma ustawioną flagę WeatherType.Thunderstorm.

0

Nie ograniczyłbym się do świata bitów. Liczniki i operatory bitowe są, jak się okazało, nie tym samym.Jeśli chcesz rozwiązać ten problem za pomocą operatorów bitowych, trzymałbym się tylko ich, tj. Nie przejmuj się wyliczeniami. Jednak ja bym coś takiego, co następuje:

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

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

To jest dokładnie to, co znaczniki znaczników (pola bitów) są przeznaczone do wykonania. Ze strony MSDN w FlagsAttribute: Pola bitowe są zwykle używane do list elementów, które mogą występować w kombinacji ... Dlatego też pola bitowe są zaprojektowane do łączenia z bitową operacją OR w celu generowania nienazwanych wartości. –

2

nie jestem pewien, że powinna ona być flagę - Myślę, że nie powinno być wejście zakres dla:

  • Temperatura
  • ile pada
  • siła wiatru
  • jakiekolwiek inne wejście masz ochotę (np burza)

można następnie użyć algorytmu do określenia, czy warunki są wystarczająco dobre.

Sądzę, że powinieneś również mieć dane na temat prawdopodobieństwa, że ​​pogoda pozostanie niezmieniona podczas jazdy na rowerze do domu. Kryteria mogą być różne - po powrocie do domu możesz brać prysznic i zmieniać się łatwiej.

Jeśli naprawdę chcesz, aby było to interesujące, zbieraj dane wejściowe z api usług pogodowych i codziennie podejmuj decyzję - tak, powinienem je włączyć lub nie, to był błąd. Być może dzięki temu aplikacja może nauczyć się podejmowania lepszych decyzji.

Kolejnym krokiem jest "uspołecznienie" swojej decyzji i sprawdzenie, czy inne osoby słyszą, że podejmujesz te same decyzje.

+1

step 4 - profit –

+0

Aww, zawsze tęsknię za krokiem! – LawrenceF

Powiązane problemy