Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Tip
Este artículo forma parte de la sección Aspectos básicos de los desarrolladores que ya conocen al menos un lenguaje de programación y están aprendiendo C#. Si no está familiarizado con la programación, comience primero con los tutoriales de introducción .
¿Viene de otro idioma? Las expresiones de C# funcionan tanto como en Java, C++y JavaScript. Una diferencia que merece la pena tener en cuenta: los operadores de asignación compuesta como += y el operador ++ de incremento son expresiones en C#, por lo que pueden aparecer en expresiones más grandes.
Una expresión es un fragmento de código que el compilador evalúa para generar un valor: un número, una cadena, una referencia o .bool Por ejemplo, 3 + 4 * 2 es una expresión que se evalúa como el entero 11y total > 10 es una expresión que se evalúa como true o false.
Las expresiones más sencillas son literales (como 42 o "hello") y nombres de variable (como total). Las expresiones más complejas se compilan mediante la combinación de otras más sencillas con operadores.
Expresiones e instrucciones
Una expresión genera un valor. Una sentencia es una instrucción completa que el programa ejecuta. Muchas sentencias contienen expresiones. Por ejemplo, int total = 3 + 4 * 2; es una instrucción de declaración de variable. El compilador evalúa la expresión 3 + 4 * 2de inicializador , que genera 11y asigna ese valor a la nueva variable total.
Puede pensar en una expresión como una frase y una instrucción de C# como una frase completa. Estas definiciones de trabajo le ayudan a comprender la terminología formal y las explicaciones que encontrará a medida que obtenga más información sobre C#, aunque la codificación normal rara vez requiere que recuerde la distinción conscientemente.
Combinar expresiones
Las expresiones se pueden combinar. Fíjese en 3 + 4 * 2. Esta expresión única contiene realmente dos expresiones más pequeñas: la expresión 4 * 2de multiplicación y la expresión3 + <result> de suma. Cuando se combinan expresiones, C# necesita una regla para decidir cuál se va a evaluar primero. Esa regla es la prioridad del operador.
No es necesario memorizar la jerarquía de precedencia completa. En la sección siguiente se resumen los grupos diarios y los paréntesis siempre le permiten hacer que el orden sea explícito cuando no esté seguro.
Precedencia del operador
La precedencia del operador determina cómo una expresión combinada agrupa en subexpresiones. Este concepto es similar a las reglas de orden de operaciones de la clase matemática. Un operador con mayor prioridad enlaza más estrechamente a sus operandos. La expresión está estructurada como si esos operandos estuvieran juntos entre paréntesis. En 3 + 4 * 2, * tiene mayor prioridad que +, por lo que la expresión agrupa como 3 + (4 * 2), no (3 + 4) * 2.
C# tiene más grupos de precedencia que los cuatro resumidos aquí. Esos grupos adicionales aplican reglas conocidas (por ejemplo, multiplicación antes de la adición) y cubren el conjunto completo de operadores. Los siguientes grupos cubren lo que se encuentra con más frecuencia en el código diario:
-
Principal, unario y rango : estos son tres grupos de precedencia distintos, todos los cuales se enlazan más estrechamente que la aritmética. Este resumen los combina en un solo paso porque, con fines prácticos, todos se aplican antes de la aritmética.
-
Operadores principales : acceso a miembros (
x.y), llamadas a métodos (f()), indexación (a[i]) y acceso condicional null (?.,?[]) se enlazan más estrechamente. -
Los operadores unarios actúan en un único operando: negación (
-x), NOT lógico (!flag), incremento de prefijo (++i) y incremento de postfijo (i++). - El operador de intervalo (
..) compila intervalos de índice para expresiones de segmento, comoarray[1..4].
-
Operadores principales : acceso a miembros (
-
Aritmética:
*, ,%/enlaza más estrechamente que+y-. La multiplicación y la división se producen antes de la suma y resta. -
Comparación —
<,>,<=,>=,==,!=se vinculan con menos fuerza que la aritmética, por lo que la aritmética se realiza antes que la comparación. -
Lógico :
&&y||enlazan menos estrechamente los operadores comunes, por lo que las comparaciones se completan antes de la combinación lógica.
Esta precedencia significa que la expresión score + bonus > threshold && attempts < maxAttempts se evalúa exactamente tal como se lee: sumar score y bonus, comparar la suma con threshold, comparar attempts con maxAttempts y, a continuación, combinar los dos resultados de bool con &&. Agregar paréntesis para que cada agrupación explícita muestre la misma estructura: ((score + bonus) > threshold) && (attempts < maxAttempts).
Para obtener la jerarquía de precedencia completa que cubre todos los operadores, consulte Operadores y expresiones de C#.
Usar paréntesis para que la intención sea clara
Los paréntesis invalidan la prioridad y documentan la intención al mismo tiempo. Cuando el orden no sea obvio de los grupos anteriores, agregue paréntesis:
int score = 80;
int bonus = 15;
int threshold = 90;
bool eligible = true;
// Without parentheses: || binds less tightly than &&, so this reads as:
// eligible && (score + bonus > threshold) || bonus > 20
bool result1 = eligible && score + bonus > threshold || bonus > 20;
// With parentheses: forces the || to combine two complete conditions
bool result2 = (eligible && score + bonus > threshold) || bonus > 20;
Console.WriteLine(result1); // => True
Console.WriteLine(result2); // => True
// Parentheses can also change the result:
bool isAdmin = false;
bool isOwner = true;
// Without: && binds tighter, so: (isAdmin && isOwner) || true
bool access1 = isAdmin && isOwner || true;
// With: forces the || to run first
bool access2 = isAdmin && (isOwner || true);
Console.WriteLine(access1); // => True (false && true is false; false || true is true)
Console.WriteLine(access2); // => False (false && anything is false)
Las dos últimas líneas muestran que los paréntesis pueden cambiar el resultado, no solo el estilo. Cuando && y || aparezcan juntos, agregue paréntesis para escribir qué condición combina primero. Un lector que ve (isAdmin && isOwner) || isSuperUser conoce la intención inmediatamente.
Cómo se evalúan las expresiones
Comprender cómo C# evalúa las expresiones combinadas es más fácil con una analogía. Piense en trabajar con un problema matemático complejo con lápiz y papel: identifique la subexpresión más interna o de prioridad más alta, calcule su valor provisional, anote el resultado y repita con la siguiente subexpresión, continuando hasta llegar a la respuesta final.
C# sigue el mismo proceso, guiado por dos reglas:
Regla 1: Los operandos se evalúan de izquierda a derecha. Para cualquier expresión binaria, ambos operandos deben evaluarse completamente antes de aplicar el operador. C# evalúa primero el operando izquierdo, luego el derecho y, a continuación, realiza la operación.
Regla 2: Algunos operadores cortocircuitan. Algunos operadores dejan de evaluarse en cuanto se determina el resultado, omitiendo los operandos restantes:
-
&&(AND condicional): devuelvefalsetan pronto como el lado izquierdo esfalse. El lado derecho nunca se evalúa. -
||(OR condicional): devuelvetruetan pronto como el lado izquierdo estrue. El lado derecho nunca se evalúa. -
?:(condicional/ternario): evalúa solo la rama que coincide con la condición ; la otra rama nunca se evalúa. -
?.(acceso de miembro condicional null) y?[](acceso a elementos condicionales NULL): detenga y devuelvanullinmediatamente cuando el lado izquierdo esnull, omitiendo el acceso o el índice del miembro. -
??=(asignación de coalescencia nula): asigna el valor de la derecha solo cuando el valor de la izquierda esnull.
Evaluación con papel y lápiz
Considere la expresión 3 + 6 / 2. Aunque la adición aparece primero en orden de lectura, / tiene mayor prioridad que +, por lo que 6 / 2 es la subexpresión que se evalúa primero. Trabajando paso a paso, exactamente como lo haría en papel:
3 + 6 / 2
↓ (evaluate 6 / 2 → 3)
3 + 3
↓ (evaluate 3 + 3 → 6)
6
// 3 + 6 / 2
// Step 1: 6 / 2 has higher precedence → interim value 3
// Step 2: 3 + 3 → final result 6
int result = 3 + 6 / 2;
Console.WriteLine(result); // => 6
El valor 3 provisional generado por 6 / 2 se convierte en el operando derecho de +y el resultado final es 6. Cada subexpresión genera un valor provisional; esos valores provisionales alimentan la siguiente subexpresión, hasta que solo permanece un valor.
La asociatividad es un concepto relacionado: cuando dos operadores tienen la misma precedencia, la asociatividad decide cuál es la primera. La mayoría de los operadores de C# son asociativos a la izquierda, lo que significa que se agrupan de izquierda a derecha. Por lo tanto a - b - c , es lo mismo que (a - b) - c, no a - (b - c).
Evaluación de cortocircuito en la práctica
La evaluación de cortocircuito es especialmente útil para las comprobaciones nulas:
string? text = null;
// Safe: second condition runs only when text is not null
bool hasContent = text != null && text.Length > 0;
Console.WriteLine(hasContent); // => False (short-circuits after null check; no NullReferenceException)
text = "hello";
hasContent = text != null && text.Length > 0;
Console.WriteLine(hasContent); // => True
// || short-circuits on true: right side is never evaluated when left side is true
string word = "hello";
bool anyMatch = word.StartsWith("h") || word.StartsWith("x");
Console.WriteLine(anyMatch); // => True (right side never evaluated)
// ?. short-circuits on null: returns null without accessing .Length
string? maybeNull = null;
int? length = maybeNull?.Length; // length is null; no NullReferenceException
Console.WriteLine(length.HasValue); // => False
text != null && text.Length > 0 es seguro porque la segunda condición solo se evalúa cuando text no es null. De forma similar, ?. detiene la evaluación cuando encuentra una referencia null, evitando un NullReferenceException sin una comprobación explícita de if.
Para obtener un vistazo más amplio a los operadores seguros para valores NULL, consulte Operadores NULL de C#.
Véase también
- Operadores y expresiones de C# (referencia de lenguaje): tabla de precedencia completa y cada operador
- Operadores aritméticos, de comparación, lógicos y de asignación : los operadores cotidianos en profundidad
-
Comparaciones de igualdad: cómo
==funciona ,!=yEquals -
Operadores NULL de C# :
?.,??y??= - Operadores lógicos booleanos