2009-05-27 16 views
22

En JavaScript existe la idea de los valores truey y falsy.C# truthy y falsy values ​​

p. Ej.

  • 0: Siempre falsa
  • 1: Siempre verdaderos
  • '0': siempre es cierto
  • '1': Siempre fiel

¿Existe una lista equivalente de Truthy y Falsey- valores en el lenguaje C# en .NET Framework?

La razón me gustaría saber esto es que me encuentro haciendo lo siguiente

if(obj != null) 
{ 
    // Do something with the object 
} 

Cuando yo podría escribir la siguiente

if(obj) 
{ 
    // Do something with the object 
} 

Respuesta

38

C# solo tiene valores de literal true y false.

C# requiere que sea muy explícito en sus declaraciones, ya que es un lenguaje fuertemente tipado, a diferencia de JavaScript que puede hacer conversiones implícitas cuando sea necesario.

Es importante tener en cuenta que "tipado fuerte" no es la razón por la cual C# no se convierte implícitamente en valores "truey/falsy". El lenguaje intencionalmente trata de evitar las trampas de otros lenguajes compilados como C++ donde ciertos valores pueden ser ciertos, como '0' o '1' que podrían permitirle cometer un error sintáctico que tal vez no note hasta el tiempo de ejecución cuando su código se comporte inesperadamente .

+1

Ok, supongo que eso responde mi pregunta :) – Alex

+5

Así que todos los dinosaurios pueden dejar de escribir si (0 == i) ... – Benjol

+1

-1; hay algunos problemas aquí. En primer lugar, malgastas el término "literal" en tu primera oración; una expresión que no es un literal todavía puede ser un booleano (por ejemplo, '1 == 1'). En segundo lugar, la afirmación de que nada es verídico o falso, excepto booleanos, es falsa, como se cubre en otras respuestas aquí. En tercer lugar, el comienzo de su tercer párrafo no tiene mucho sentido. La falta de conversión implícita es la * definición * de tipificación fuerte (o al menos la más común, es un término algo nebuloso y sobrecargado); en realidad está diciendo que la tipificación fuerte no es la razón de ello, lo cual es extraño. –

0

Si obj es un tipo que ha creado, puede definir una conversión implícita definida por el usuario a bool.

+1

No recomendaría esto como 'mejor práctica' aunque ... – dtb

+0

¡Yo tampoco! Esta es la única forma que conozco de obtener la sintaxis que Alex está pidiendo. –

13

Respuesta corta:

En C#:

  • cierto: siempre cierto
  • falsa: Siempre falsa

Todo lo demás no es un valor booleano.

+0

No es cierto. Ver mi respuesta a continuación. – Trumpi

+0

Mi respuesta no está en contradicción con la suya. Los tipos pueden implementar conversiones implícitas a bool o su operador 'verdadero', pero cualquier valor de ese tipo todavía no es del tipo 'bool' :) – dtb

+0

Leí su respuesta nuevamente: en realidad contradice la especificación. – Trumpi

3

La sentencia evalúa algo que se puede convertir en/equivale a/Boolean, o un valor lógico en sí ... la comprobación de nula como obj! = Null es un tal expresión,

'si (obj) 'puede funcionar si solo si obj puede convertirse a bool, no si es nulo.

-4

C# es un lenguaje de tipo estático, es decir, el tipo de objetos importan al configurar lo que es.

Por ejemplo, "4"! = 4.

JavaScript, sin embargo es un lenguaje de tipo dinámico, por lo que los tipos tienen poca importancia.

Así que en JavaScript, "4" == 4.

Los valores "Truthy" son valores que acaba de pasar a satisfacer x == true, mientras que los valores "Falsey" no lo hacen.

Sin seguridad de tipo, ciertas características como la sobrecarga producirán comportamientos impredecibles.

Para obtener más información, puede ver here.

+3

No, el tipado dinámico Vs estático no tiene nada que ver con esto. –

10

Este tipo de código no se compilará (y debería). Si desea anular específicamente ese comportamiento, puede crear un implicit conversion como booleano. Algo como esto:

public class Foo { 
    public static implicit operator bool(Foo me) { 
     if (me == null) { 
      return false; 
     } 

     return true; // maybe add more logic before saying True 
    } 
} 

Yo llamaría a eso una mala práctica porque, a un codificador que no están familiarizados con su proyecto, que no es inmediatamente claro qué lógica se alimenta la conversión booleana. La forma más idiomática para hacer esto sería indicar explícitamente al lector lo que el código está haciendo, como el construido en la clase String hace, con una función auxiliar estática:

if (String.IsNullOrEmpty(str){ 
    // ... 
} 

Código solamente se escribe una vez y leer muchas veces ; optimizar para la legibilidad

+0

+1 (00000 si pudiera) por mencionar legibilidad y comprensibilidad. La lógica implícita en demasiados lugares puede matar proyectos. – Phil

15

La respuesta correcta a su pregunta se encuentra en la sección 7.19 de la especificación C# 3.0, que puede encontrar fácilmente en Internet. Para su comodidad, el texto pertinente es:

7.19 expresiones booleanas

Un booleano-expresión es una expresión que produce un resultado de tipo bool.

La expresión condicional de control de un enunciado [...] if es una expresión booleana . [...]

se requiere A-expresión booleana para ser de un tipo que puede ser implícitamente convertidos a bool o de un tipo que implementa operador cierto. Si no se cumple ninguno de los requisitos de , se produce un error de tiempo de compilación .

Cuando una expresión booleana es de un tipo que no se puede convertir implícitamente a bool pero que implementar operador cierto, continuación, después de la evaluación de la expresión , el operador verdadera aplicación proporcionada por ese tipo se invoca para producir un valor bool.

No hay distintos tipos bool sí que son convertir implícitamente a bool a través de una conversión incorporada, pero por supuesto, las conversiones implícitas definidas por el usuario a Bool puede ser definido por el usuario.

20

De forma predeterminada, C# solo proporciona true y false.

Sin embargo, puede hacer que sus propios tipos personalizados se conviertan en "truey" y "falsey" implementando el operador true. Cuando un tipo implementa el operador true, las instancias de ese tipo se pueden usar como una expresión booleana. De la sección 7.19 de la C# Language Specification:

Cuando una expresión booleana es de un tipo que no se puede convertir implícitamente a bool pero hace implementar operador cierto, entonces después de la evaluación de la expresión, el operador verdadera aplicación proporcionada por ese tipo se invoca para producir un valor de bool

El tipo de estructura DBBool en §11.4.2 proporciona un ejemplo de un tipo que implementa operador verdadero y operador falso.

Este es un fragmento de código de una declaración del operador true (que probablemente hará lo que quería hacer en su pregunta):

public static bool operator true(MyType myInstance) 
{ 
    return myInstance != null; 
} 

Si implementa el operador true, entonces debe implementar el operador false también.

+5

Esta es la respuesta correcta. Todas las respuestas que no mencionan las sobrecargas falsas del operador verdadero/operador son algo incompletas.También es correcto que lo que el OP intenta hacer no es realmente una buena idea, pero esta es la mejor manera de hacerlo. –

+0

Si implementa el operador verdadero, también debe implementar el operador falso. -> eso es extraño. ¿No debería el resultado del falso operador ser siempre (verdadero operador)? – David

+0

Me parece que sería preferible implementar una conversión implícita a bool en lugar de los operadores 'true' y' false', ¿no? Un método en lugar de dos, y ninguna posibilidad de cometer un error cuando los dos métodos son inconsistentes entre sí. –

1

Las respuestas anteriores son correctas. Sin embargo, tengo un método de extensión que utilizo en algunos casos raros:

public static bool IsTruthy(this object obj) 
{ 
    if (obj == null || obj is DBNull) 
     return false; 

    var str = obj as string; 
    if (str != null) 
     return !string.IsNullOrWhiteSpace(str) && 
      !str.Trim().Equals(bool.FalseString, StringComparison.OrdinalIgnoreCase); 

    try 
    { 
     if (Convert.ToDecimal(obj) == 0) 
      return false; 
    } 
    catch { } 

    if (obj is BigInteger) 
     return ((BigInteger)obj) != 0; 

    return true; 
} 

Algunas notas sobre este:

  • Este método es incompatible con la forma en javascript se encarga de la cadena "false"
  • Este el método devuelve verdadero para los enumerables vacíos, que es coherente con javascript
+0

'que uso en algunos casos raros' ¿Puedes dar algunos ejemplos de cuándo has necesitado usar Truthy, Falsey comprueba en C#. Nunca he escuchado que alguien necesite esto en el mundo de .Net. – Shiva

+0

No puedo recordar y al buscar en mi carpeta de códigos no encontré nada. Parece difícil de imaginar, pero estoy seguro de que tenía mis razones. ¯ \ _ (ツ) _/¯ –

0

Puede definir su propia verdad y falsy por medio de métodos de extensión.

public static bool Falsy(this object obj) { 
     if(obj == null) return true; 
     if (obj is string) 
      if(obj as string == string.Empty) return true; 
     if(obj is byte) 
      if((byte)obj == 0) return true; 
     if(obj is sbyte) 
      if((sbyte)obj == 0) return true; 
     if(obj is short) 
      if((short)obj == 0) return true; 
     if(obj is ushort) 
      if((ushort)obj == 0) return true; 
     if(obj is int)    
      if((int)obj == 0) return true; 
     if(obj is uint) 
      if((uint)obj == 0) return true; 
     if(obj is long) 
      if((long)obj == 0) return true; 
     if(obj is ulong) 
      if((ulong)obj == 0) return true; 
     if(obj is float) 
      if((float)obj == 0) return true; 
     if(obj is double) 
      if((double)obj == 0) return true; 
     if(obj is decimal) 
      if((decimal)obj == 0) return true; 
     if(obj is IEnumerable<object>) 
      if((obj as IEnumerable<object>).Count<object>() == 0) 
       return true; 
     if(obj is Array) 
      if(((Array)obj).Length <= 0) 
       return true; 
     if(obj is ObjectId) 
      if(((ObjectId)obj).Pid == 0) return true; 
     if(obj is System.Collections.ObjectModel.ObservableCollection<M>) 
      if(((ObservableCollection<M>)obj).Count <= 0) return true; 
       return false; 
} 

public static bool Truthy(this object obj) { 
    return !Falsy(obj); 
} 

Así que usted puede hacer algo como:

si (customerList.Falsy()) {throw new Excepción ("No puede ser nulo o vacío"); }

Cuestiones relacionadas