c# - tipos - si las declaraciones coinciden con mĂșltiples valores
variables alfanumericas en c# (14)
Alternativamente, y esto le daría más flexibilidad si prueba para valores distintos a 1 o 2 en el futuro, es usar una declaración de cambio
switch(value)
{
case 1:
case 2:
return true;
default:
return false
}
¿Alguna forma más fácil de escribir esta declaración if?
if (value==1 || value==2)
Por ejemplo ... en SQL puede decir where value in (1,2)
lugar de where value=1 or value=2
.
Estoy buscando algo que funcione con cualquier tipo básico ... cadena, int, etc.
En general, no.
Sí, hay casos en que la lista se encuentra en una Array
o List
, pero ese no es el caso general.
En vb.net o C # esperaría que el enfoque general más rápido para comparar una variable con un número razonable de objetos nombrados por separado (en lugar de, por ejemplo, todas las cosas en una colección) sea simplemente comparar cada objeto contra la comparación y mucho como lo has hecho Es ciertamente posible crear una instancia de una colección y ver si contiene el objeto, y hacerlo puede ser más expresivo que comparar el objeto contra todos los elementos individualmente, pero a menos que uno use una construcción que el compilador pueda reconocer explícitamente, dicho código casi seguramente será mucho más lento que simplemente haciendo las comparaciones individuales. No me preocuparía la velocidad si el código, por su naturaleza, se ejecuta a lo sumo unos cientos de veces por segundo, pero desconfiaría de que el código se reordene a algo que se ejecuta mucho más a menudo de lo previsto originalmente.
Un enfoque alternativo, si una variable es algo así como un tipo de enumeración, es elegir valores de enumeración de potencia de dos para permitir el uso de máscaras de bits. Si el tipo de enumeración tiene 32 o menos valores válidos (por ejemplo, comenzar Harry = 1, Ron = 2, Hermione = 4, Ginny = 8, Neville = 16) uno podría almacenarlos en un entero y verificar múltiples bits a la vez en un solo operación ((if ((thisOne & (Harry | Ron | Neville | Beatrix))! = 0) / * Hacer algo * /. Esto permitirá un código rápido, pero está limitado a enumeraciones con un pequeño número de valores.
Un enfoque algo más poderoso, pero que debe usarse con cuidado, es usar algunos bits del valor para indicar atributos de algo, mientras que otros bits identifican el elemento. Por ejemplo, el bit 30 podría indicar que un personaje es masculino, el bit 29 podría indicar que es amigo de Harry, etc., mientras que los bits inferiores distinguen entre caracteres. Este enfoque permitiría agregar personajes que pueden ser o no amigos de Harry, sin que sea necesario cambiar el código que busca el amigo de Harry. Una advertencia al hacer esto es que se debe distinguir entre las constantes de enumeración que se usan para ESTABLECER un valor de enumeración y las que se usan para PROBAR. Por ejemplo, para establecer una variable que indique Harry, puede que desee establecerlo en 0x60000001, pero para ver si una variable es Harry, uno debe probarla con 0x00000001.
Un enfoque más, que puede ser útil si el número total de valores posibles es moderado (por ejemplo, 16-16,000 o más) es tener una matriz de indicadores asociados con cada valor. Entonces uno podría codificar algo como "if (((characterAttributes [theCharacter] & chracterAttribute.Male)! = 0)". Este enfoque funcionará mejor cuando el número de caracteres sea bastante pequeño. Si la matriz es demasiado grande, la caché falla puede ralentizar baje el código hasta el punto en que las pruebas contra un pequeño número de caracteres individualmente serían más rápidas.
Es esto lo que estás buscando ?
if (new int[] { 1, 2, 3, 4, 5 }.Contains(value))
Más fácil es subjetivo, pero tal vez la declaración de cambio sería más fácil? No tiene que repetir la variable, por lo que pueden caber más valores en la línea, y una línea con muchas comparaciones es más legible que la contraparte que usa la instrucción if.
Qué tal si:
if (new[] {1, 2}.Contains(value))
Aunque es un hack :)
O si no te importa crear tu propio método de extensión, puedes crear lo siguiente:
public static bool In<T>(this T obj, params T[] args)
{
return args.Contains(obj);
}
Y puedes usarlo así:
if (1.In(1, 2))
:)
Si busca muchas veces un valor en una lista fija de valores en una lista larga, se debe usar HashSet <T> . Si la lista es muy corta (<~ 20 elementos), List podría tener un mejor rendimiento, basado en esta prueba HashSet vs. List performance
HashSet<int> nums = new HashSet<int> { 1, 2, 3, 4, 5 };
// ....
if (nums.Contains(value))
Si tiene una Lista, puede usar .Contains (suObjeto), si solo está buscando que exista (como un where). De lo contrario, mire el método de extensión Linq. Any ().
Tuve el mismo problema, pero lo resolví con un interruptor de declaración de cambio (un valor que está encendiendo) {caso 1: el código que desea que suceda; caso 2: el código que desea que suceda; predeterminado: devolver un valor}
Un método de extensión como este lo haría ...
public static bool In<T>(this T item, params T[] items)
{
return items.Contains(item);
}
Úselo así:
Console.WriteLine(1.In(1,2,3));
Console.WriteLine("a".In("a", "b"));
Una forma más complicada :) que emula el ''IN'' de SQL:
public static class Ext {
public static bool In<T>(this T t,params T[] values){
foreach (T value in values) {
if (t.Equals(value)) {
return true;
}
}
return false;
}
}
if (value.In(1,2)) {
// ...
}
Pero ve por la forma estándar, es más legible.
EDITAR : una mejor solución, según la sugerencia de @ Kobi:
public static class Ext {
public static bool In<T>(this T t,params T[] values){
return values.Contains(t);
}
}
Usando Linq,
if(new int[] {1, 2}.Contains(value))
Pero tendría que pensar que tu original es más rápido.
Usando métodos de extensión:
public static class ObjectExtension
{
public static bool In(this object obj, params object[] objects)
{
if (objects == null || obj == null)
return false;
object found = objects.FirstOrDefault(o => o.GetType().Equals(obj.GetType()) && o.Equals(obj));
return (found != null);
}
}
Ahora puedes hacer esto:
string role= "Admin";
if (role.In("Admin", "Director"))
{
...
}
public static bool EqualsAny<T>(IEquatable<T> value, params T[] possibleMatches) {
foreach (T t in possibleMatches) {
if (value.Equals(t))
return true;
}
return false;
}
public static bool EqualsAny<T>(IEquatable<T> value, IEnumerable<T> possibleMatches) {
foreach (T t in possibleMatches) {
if (value.Equals(t))
return true;
}
return false;
}