2010-10-07 15 views
5

el siguiente lambda statemement devuelve nulo, cuando esperaba que devolviera un valor de cadena.¿Cómo puedo usar linq para verificar si una enumeración de flags/bitwise contiene un tipo?

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

ahora la propiedad AddressType de la instancia actual estoy interrigating contiene los siguientes datos:

AddressType.Political | AddressType.Country

por lo que es que contiene dos valores.

Por supuesto, mi lambda no funcionará, porque el valor del país (supongamos que es 1)! = El valor de bit a bit político o país (supongamos que es 1 | 2 == 3).

¿Alguna idea?

Me preocupa tengo que tener algo realmente feo como fraking ...

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

.. pensamientos?

Respuesta

8

.NET 4.0 tiene la Enum.HasFlag método:

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

Si usted no está en .NET 4.0, el bit a bit AND que tienes ahí es una buena opción. Si no le gusta el patrón, consulte UnconstrainedMelody, que tiene un método de extensión para este propósito. Alternativamente, puede escribir uno usted mismo; esta pregunta probablemente sea de ayuda: Anyone know a good workaround for the lack of an enum generic constraint?

+0

SERIOUS?/brb .... HAHAHAH frak me :) ¡Lo hace también! Ganar. ganar y el-winno-win !!! ¿Qué tal si quieres verificar DOS banderas? por ejemplo, AddressType.Country o AddressType.Foo? puede HasFlag (AddressType.Country) | AddressType.Foo) ¿funciona? * (observe el único carácter PIPE) * –

+0

@ Pure.Krome: Sí, eso debería funcionar. Desde MSDN: "El método HasFlag devuelve el resultado de la siguiente expresión booleana: thisInstance And flag = flag" – Ani

5

Exijo precaución con Enum.HasFlag en .NET 4.0. Cuando diseñé mi aplicación informática, utilizando ANTS 6.0, esta función apareció cerca de la parte superior. Volviendo a la antigua prueba de indicador de bit manual, obtuve un factor de> 100 aceleración en mi caso. Hasta que se resuelva este error de BCL, considérese aconsejado:

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

Ahora que ES interesante ... Me pregunto si Jon + otros tienen algún conocimiento de esto? –

+0

Lamentablemente, esto es cierto, bien conocido y explicado aquí - http://www.codeproject.com/Tips/441086/NETs-Enum-HasFlag-and-performance-costs –

Cuestiones relacionadas