2010-08-21 11 views
5

un semplice codice:Bit Flags - Cosa mi manca?

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); 
} 

Un aiuto:

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); } 

uscita di oggi (Sabato)

now.DayOfWeek: Saturday 
True 
True 
True 
True 
True 
True 

Ma l'uscita dovrebbe essere come:

now.DayOfWeek: Saturday 
False 
False 
False 
True 
True 
True 

Wh sono qui che mi manca?

risposta

11

I giorni della settimana non sono flag di bit. http://msdn.microsoft.com/en-us/library/system.datetime.dayofweek.aspx

Il valore delle costanti nell'enumerazione DayOfWeek varia da DayOfWeek.Sunday a DayOfWeek.Saturday. Se si esegue il cast su un intero , il suo valore varia da zero (che indica DayOfWeek.Sunday) a sei (che indica DayOfWeek.Saturday).

+0

0 (Domenica) a 6 (Sabato). – sisve

+0

Sapevo di essere stato stupido :(Grazie per avermi segnalato i documenti ... Continuo a dimenticare che sono una parte importante del ruolo di sviluppatore ... ma ho davvero supposto che DayOfWeek fosse un Enum di bandiera: o ( – balexandre

1

DayOfWeek ha numeri sequenziali.

Utilizzare un List<DayOfWeek>.

Vai alla definizione mostra:

// 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 ... quindi non è possibile applicare operatori di bit in cui in questo esempio sono i migliori da utilizzare! – balexandre

+0

No. Ma il meglio può essere da un punto di vista prematuro di ottimizzazione delle prestazioni, non dal punto di vista della leggibilità. sono più facili da leggere –

2

Si potrebbe creare il proprio enum DayOfWeek se avete bisogno di usarlo come bandiere:

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

sì, ho finito per farlo :) ma ho pensato erroneamente che DayOfWeek fosse un Enum di bandiera ... Grazie. – balexandre

0

La DayOfWeek enumerazione è stato progettato per rappresentare un solo giorno di la settimana, non un set di giorni.

Non si ottiene un errore del compilatore per l'utilizzo di & perché le enumerazioni sono numeri interi, ma l'operatore non fa ciò che si aspetta (a meno che non si verifichi solo la pianificazione degli eventi il ​​lunedì, il martedì o il giovedì).

Se si desidera un bit flag, quindi dichiarare un bit di tipo flag, come suggerito da Ray.

+0

sì ... il mio errore stava presumendo che DayofWeek fosse un tipo a bandiera. .. non mi capita mai in nessun altro modo ... stupido :-( – balexandre

5

So che questo è un vecchio post, ma solo nel caso in cui - una sintassi ordinato di fare bandiere enumerazioni è

[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 
} 

Si avrebbe bisogno Nessuno per indicare nulla è stato selezionato. Tale enum consente di indicare più giorni, ad esempio:

var selectedDays = DaysOfWeek.Tuesday | DaysOfWeek.Friday; 

Nessun commento è necessario si spera. E al fine di "decodificare" il valore:

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

E questo poi ci permette di chiamare:

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

Spero che questo aiuti qualcuno.

+1

Vorrei andare con il metodo di estensione, qualcosa come: 'public static bool IsDayOfWeekSelected (questo DaysOfWeek selectedDays, DaysOfWeek quale) {return selection & wh ich == quale; } 'allora si potrebbe facilmente fare:' selectedDays.IsDayOfWeekSelected (DaysOfWeek.Tuesday); '; o) – balexandre

+0

Buon punto. Non è necessario inserirlo in una classe di utilità :) –

+0

Avrei sempre impostato "Nessuno" su 0, e puoi anche usare 'Domenica = 1 << DayOfWeek.Sunday' ecc per mappare su .NET' DayOfWeek' –

Problemi correlati