2010-08-21 8 views
5

ein einfacher Code:Bit Flags - Was fehlt mir?

protected void Page_Load(object sender, EventArgs e) 
{ 
    DateTime now = DateTime.UtcNow; 

    lit.Text += "<br/>now.DayOfWeek: " + now.DayOfWeek.ToString(); 

    // weekdays (Saturday is not included) 
    DayOfWeek runningDays = DayOfWeek.Monday | DayOfWeek.Tuesday | DayOfWeek.Wednesday | DayOfWeek.Thursday | DayOfWeek.Friday; 

    lit.Text += "<br/>" + runningDays.HasFlag(now.DayOfWeek); 
    lit.Text += "<br/>" + runningDays.HasAny(now.DayOfWeek); 
    lit.Text += "<br/>" + ((runningDays & now.DayOfWeek) != 0); 

    // weekend (Saturday is in a weekend) 
    runningDays = DayOfWeek.Saturday | DayOfWeek.Sunday; 

    lit.Text += "<br/>" + runningDays.HasFlag(now.DayOfWeek); 
    lit.Text += "<br/>" + runningDays.HasAny(now.DayOfWeek); 
    lit.Text += "<br/>" + ((runningDays & now.DayOfWeek) != 0); 
} 

Ein Helfer:

public static bool HasExactly(this DayOfWeek x, DayOfWeek y) { return x == y; } 
public static bool HasAny(this DayOfWeek x, DayOfWeek y) { return 0 != (x & y); } 
public static bool HasAll(this DayOfWeek x, DayOfWeek y) { return y == (x & y); } 

heutige Ausgabe (Samstag)

now.DayOfWeek: Saturday 
True 
True 
True 
True 
True 
True 

Aber die Ausgabe sollte wie:

now.DayOfWeek: Saturday 
False 
False 
False 
True 
True 
True 

Wh bei vermisse ich hier?

Antwort

11

Wochentage sind keine Bit-Flags.

http://msdn.microsoft.com/en-us/library/system.datetime.dayofweek.aspx

Der Wert der Konstanten in der DayOfWeek Aufzählung reicht von DayOfWeek.Sunday zu DayOfWeek.Saturday. Bei einer Umwandlung in eine Ganzzahl reicht der Wert von (was DayOfWeek.Sunday anzeigt) bis six (was auf DayOfWeek.Saturday hinweist).

+0

0 (Sonntag) bis 6 (Samstag). – sisve

+0

Ich wusste, dass ich dumm war :(Danke, dass du mich auf die Dokumente aufmerksam gemacht hast ... Ich vergesse ständig, dass sie ein wichtiger Teil der Entwicklerrolle sind ... aber ich habe wirklich angenommen, dass DayOfWeek eine Flag Enum war: o ( – balexandre

1

DayOfWeek hat fortlaufende Nummern.

Verwenden Sie eine List<DayOfWeek>.

Zur Definition zeigt:

// Summary: 
//  Specifies the day of the week. 
[Serializable] 
[ComVisible(true)] 
public enum DayOfWeek 
{ 
    // Summary: 
    //  Indicates Sunday. 
    Sunday = 0, 
    // 
    // Summary: 
    //  Indicates Monday. 
    Monday = 1, 
    // 
    // Summary: 
    //  Indicates Tuesday. 
    Tuesday = 2, 
    // 
    // Summary: 
    //  Indicates Wednesday. 
    Wednesday = 3, 
    // 
    // Summary: 
    //  Indicates Thursday. 
    Thursday = 4, 
    // 
    // Summary: 
    //  Indicates Friday. 
    Friday = 5, 
    // 
    // Summary: 
    //  Indicates Saturday. 
    Saturday = 6, 
} 
+0

err ... dann können Sie keine Bitoperatoren anwenden, in denen in diesem Beispiel die besten zu verwenden sind! – balexandre

+0

Nein. Aber das beste kann aus einer vorschnellen Optimierungsperformance sein, nicht aus Lesbarkeitsgesichtspunkten. List.Contains, usw. sind einfacher zu lesen –

2

Sie könnten Ihre eigene DayOfWeek Enum erstellen, wenn Sie es wie Flaggen verwenden müssen:

[Flags] 
public enum MyDayOfWeek { Sunday = 1, Monday = 2, Tuesday = 4, ... , Saturday = 64 }; 
+0

ja, ich habe das getan :) aber ich habe fälschlicherweise angenommen, dass DayOfWeek ein Flag Enum war ... Danke ... – balexandre

0

Die DayOfWeek Aufzählung wurde entwickelt, einen einzigen Tag zu vertreten die Woche, nicht eine Reihe von Tagen.

Sie erhalten keinen Compilerfehler für die Verwendung von &, da enums Ganzzahlen sind, aber der Operator nicht das tut, was Sie erwarten (es sei denn, Sie planen nur Ereignisse montags, dienstags oder donnerstags).

Wenn Sie ein Bit-Flag möchten, dann deklarieren Sie einen Bit-Flag-Typ, wie von Ray vorgeschlagen.

+0

yep ... mein Fehler ging davon aus, dass DayofWeek ein bisschen Flaggentyp war. .. es kommt mir nie anders vor ... dumme mich :-( – balexandre

5

Ich weiß, dass dies eine alte Post ist aber nur für den Fall - eine saubere Syntax-Flags Aufzählungen zu tun ist,

[Flags] 
public enum DaysOfWeek 
{ 
    None = 1 << 0, 
    Monday = 1 << 1, 
    Tuesday = 1 << 2, 
    Wednesday = 1 << 3, 
    Thursday = 1 << 4, 
    Friday = 1 << 5, 
    Saturday = 1 << 6, 
    Sunday = 1 << 7 
} 

Sie würden keine brauchen nichts dafür ausgewählt wurde. Eine solche Enumeration ermöglicht es Ihnen, mehrere Tage anzugeben, zum Beispiel:

Kein Kommentar erforderlich hoffentlich. Und um zu "entschlüsseln", um den Wert:

public bool IsDayOfWeekSelected(DaysOfWeek which, DaysOfWeek selection) 
{ 
    return selection & which == which; 
} 

Und dann können wir rufen Sie an:

var isTuesday = IsDayOfWeekSelected(DaysOfWeek.Tuesday, selectedDays); // => true 
var isWednesday = IsDayOfWeekSelected(DaysOfWeek.Wednesday, selectedDays); // => false 
var isFriday = IsDayOfWeekSelected(DaysOfWeek.Friday, selectedDays); // => true 

Hope this jemand hilft.

+1

Ich würde mit Extension Method gehen, so etwas wie: 'public static bool IsDayOfWeekSelected (diese DaysOfWeek selectedDays, DaysOfWeek welche) {return selection & wh ich == was; } 'dann könnten Sie einfach tun:' selectedDays.IsDayOfWeekSelected (DaysOfWeek.Tuesday); '; o) – balexandre

+0

Guter Punkt. Sie müssen es nicht in eine Utility-Klasse stopfen :) –

+0

Ich würde immer 'None' auf 0 voreinstellen, und Sie können auch' Sunday = 1 << DayOfWeek.Sunday' usw. verwenden, um .NET zuzuordnen DayOfWeek' –

Verwandte Themen