2010-10-07 15 views
5

il seguente stato lambda restituisce null, quando speravo che restituisse un valore stringa.Come posso usare linq per verificare se un flag/enumerazione bitwise contiene un tipo?

var countryCode = AddressComponents 
    .Where(x => x.AddressType == AddressType.Country) 
    .Select(x => x.ShortName) 
    .SingleOrDefault(); 

ora di proprietà AddressType dell'istanza corrente sto interrigating contiene i seguenti dati:

AddressType.Political | AddressType.Country

in modo che sia contenente due valori.

Ovviamente, il mio lambda non funzionerà, perché il valore del paese (assumiamo che sia 1)! = Il valore di Political bitwise o Paese (assumiamo che sia 1 | 2 == 3).

Qualche idea?

Sono preoccupato ho bisogno di avere qualcosa di veramente brutto come fraking ...

((AddressTypes & AddressType.Country) == AddressType.Country)

.. pensieri?

risposta

8

NET 4.0 ha il metodo Enum.HasFlag:

x => x.AddressType.HasFlag(AddressType.Country) 

Se non siete su .NET 4.0, il bit AND che hai lì è una buona scelta. Se non ti piace il modello, controlla UnconstrainedMelody, che ha un metodo di estensione per questo scopo. In alternativa, puoi scriverne uno da solo; questa domanda sarà probabilmente di aiuto - Anyone know a good workaround for the lack of an enum generic constraint?

+0

SERIO ?!/brb .... HAHAHAH mi sfiora :) Lo fa anche lui! Vincere. vincere ed el-winno-win !!! Che dire se vuoi controllare DUE flag. ad esempio AddressType.Country o AddressType.Foo? può HasFlag (AddressType.Country) | AddressType.Foo) lavoro? * (nota il carattere PIPE singolo) * –

+0

@ Pure.Krome: Sì, dovrebbe funzionare. Da MSDN: "Il metodo HasFlag restituisce il risultato della seguente espressione booleana: thisInstance And flag = flag" – Ani

5

Esorto con Enum.HasFlag in .NET 4.0. Quando ho profilato la mia app legata all'elaborazione, usando ANTS 6.0, questa funzione si avvicinava in alto. Tornando al vecchio test del bit flag manuale, nel mio caso si è verificato un fattore di accelerazione> 100. Fino a quando questo errore BCL non viene risolto, si consideri consigliato:

using System; 
using System.Diagnostics; 

class Program 
{ 
    [Flags] enum test { flag1 = 1, flag2 = 2, flag4 = 4 } 

    static void Main(string[] args) 
    { 
     Stopwatch s; 
     test t = test.flag4; 

     s = Stopwatch.StartNew(); 
     for (int c=0,i=0; i < 50000000; i++) 
      if (t.HasFlag(test.flag2)) 
       c++; 
     Console.WriteLine(s.ElapsedMilliseconds); // 22837 ms. 

     s = Stopwatch.StartNew(); 
     for (int c=0,i=0; i < 50000000; i++) 
      if ((t & test.flag2) > 0) 
       c++; 
     Console.WriteLine(s.ElapsedMilliseconds); // 172 ms. 
    } 
} 
+0

Ora che IS è interessante .... Mi chiedo se Jon + altri non ne abbia conoscenza? –

+0

Purtroppo questo è vero, ben noto e spiegato qui - http://www.codeproject.com/Tips/441086/NETs-Enum-HasFlag-and-performance-costs –

Problemi correlati