C# Language
Los operadores
Buscar..
Introducción
En C #, un operador es un elemento de programa que se aplica a uno o más operandos en una expresión o declaración. Los operadores que toman un operando, como el operador de incremento (++) o nuevo, se denominan operadores unarios. Los operadores que toman dos operandos, como los operadores aritméticos (+, -, *, /), se denominan operadores binarios. Un operador, el operador condicional (? :), toma tres operandos y es el único operador ternario en C #.
Sintaxis
- Operador público OperandType operador operatorSymbol (OperandType operand1)
- Operador público OperandType operador operatorSymbol (OperandType operand1, OperandType2 operand2)
Parámetros
Parámetro | Detalles |
---|---|
símbolo de operador | El operador está sobrecargado, por ejemplo, +, -, /, * |
OperandType | El tipo que será devuelto por el operador sobrecargado. |
operando1 | El primer operando que se utilizará en la realización de la operación. |
operando2 | El segundo operando que se utilizará para realizar la operación, cuando se realizan operaciones binarias. |
declaraciones | Código opcional necesario para realizar la operación antes de devolver el resultado. |
Observaciones
Todos los operadores se definen como static methods
y no son virtual
y no se heredan.
Precedencia del operador
Todos los operadores tienen una "precedencia" particular según el grupo al que pertenezca el operador (los operadores del mismo grupo tienen la misma prioridad). Lo que significa que algunos operadores se aplicarán antes que otros. Lo que sigue es una lista de grupos (que contienen sus respectivos operadores) ordenados por precedencia (el más alto primero):
Operadores primarios
-
ab
- Acceso de miembros. -
a?.b
- Acceso de miembro condicional nulo. -
->
- Desreferenciación de punteros combinada con acceso de miembros. -
f(x)
- Invocación de la función. -
a[x]
- indexador. -
a?[x]
- Indizador condicional nulo. -
x++
- Incremento de Postfix. -
x--
-x--
Postfix. -
new
- Tipo de instanciación. -
default(T)
: devuelve el valor inicializado predeterminado de tipoT
-
typeof
- Devuelve el objetoType
del operando. -
checked
: habilita la comprobación de desbordamiento numérico. -
unchecked
marcar - Desactiva la comprobación de desbordamiento numérico. -
delegate
: declara y devuelve una instancia de delegado. -
sizeof
: devuelve el tamaño en bytes del operando de tipo.
-
Operadores Unarios
-
+x
- Devuelvex
. -
-x
- Negación numérica. -
!x
- Negación lógica. -
~x
- Bitwise complemento / declara destructores. -
++x
- Incremento de prefijo. -
--x
---x
prefijo. -
(T)x
- Tipo de fundición. -
await
- espera unaTask
. -
&x
- Devuelve la dirección (puntero) dex
. -
*x
- Desreferenciación del puntero.
-
Operadores Multiplicativos
-
x * y
- Multiplicación. -
x / y
- División. -
x % y
- Módulo.
-
Operadores Aditivos
-
x + y
- Adición. -
x – y
- resta.
-
Operadores de cambio bitwise
-
x << y
- Desplazar bits a la izquierda. -
x >> y
- Desplazar bits a la derecha.
-
Operadores relacionales / de prueba de tipo
-
x < y
- Menos que. -
x > y
- Mayor que. -
x <= y
- menor o igual que. -
x >= y
- Mayor o igual que. -
is
- Compatibilidad de tipos. -
as
- Tipo de conversión.
-
Operadores de Igualdad
-
x == y
- Igualdad. -
x != y
- No es igual.
-
Operador lógico y
-
x & y
- Lógica / bit a bit AND.
-
Operador XOR lógico
-
x ^ y
- XOR lógico / bit a bit.
-
Operador lógico o
-
x | y
- Lógica / bitwise OR.
-
Condicional y operador
-
x && y
- Cortocircuito lógico AND.
-
Operador condicional o
-
x || y
- Cortocircuito lógico OR.
-
Operador de fusión nula
-
x ?? y
- Devuelvex
si no es nulo; De lo contrario, devuelvey
.
-
Operador condicional
-
x ? y : z
- Evalúa / devuelvey
six
es verdadero; De lo contrario, evalúaz
.
-
contenido relacionado
Operadores sobrecargables
C # permite que los tipos definidos por el usuario sobrecarguen a los operadores definiendo funciones miembro estáticas usando la palabra clave del operator
.
El siguiente ejemplo ilustra una implementación del operador +
.
Si tenemos una clase Complex
que representa un número complejo:
public struct Complex
{
public double Real { get; set; }
public double Imaginary { get; set; }
}
Y queremos agregar la opción de usar el operador +
para esta clase. es decir:
Complex a = new Complex() { Real = 1, Imaginary = 2 };
Complex b = new Complex() { Real = 4, Imaginary = 8 };
Complex c = a + b;
Tendremos que sobrecargar el operador +
para la clase. Esto se hace usando una función estática y la palabra clave del operator
:
public static Complex operator +(Complex c1, Complex c2)
{
return new Complex
{
Real = c1.Real + c2.Real,
Imaginary = c1.Imaginary + c2.Imaginary
};
}
Los operadores como +
, -
, *
, /
pueden estar sobrecargados. Esto también incluye a los operadores que no devuelven el mismo tipo (por ejemplo, ==
y !=
Pueden estar sobrecargados, a pesar de los booleanos que regresan).
Los operadores de comparación deben estar sobrecargados en pares (por ejemplo, si <
está sobrecargado, >
también debe sobrecargarse).
Una lista completa de operadores sobrecargables (así como operadores no sobrecargables y las restricciones impuestas a algunos operadores sobrecargables) puede verse en MSDN - Operadores sobrecargables (Guía de programación de C #) .
la sobrecarga del operator is
se introdujo con el mecanismo de coincidencia de patrones de C # 7.0. Para más detalles, ver el patrón de coincidencia
Dado un tipo Cartesian
definido como sigue
public class Cartesian
{
public int X { get; }
public int Y { get; }
}
Un operator is
sobrecargable podría, por ejemplo, definirse para coordenadas Polar
public static class Polar
{
public static bool operator is(Cartesian c, out double R, out double Theta)
{
R = Math.Sqrt(c.X*c.X + c.Y*c.Y);
Theta = Math.Atan2(c.Y, c.X);
return c.X != 0 || c.Y != 0;
}
}
que puede ser usado como este
var c = Cartesian(3, 4);
if (c is Polar(var R, *))
{
Console.WriteLine(R);
}
(El ejemplo está tomado de la documentación de Roslyn Pattern Matching )
Operadores relacionales
Es igual a
Comprueba si los operandos (argumentos) suministrados son iguales
"a" == "b" // Returns false.
"a" == "a" // Returns true.
1 == 0 // Returns false.
1 == 1 // Returns true.
false == true // Returns false.
false == false // Returns true.
A diferencia de Java, el operador de comparación de igualdad trabaja de forma nativa con cadenas.
El operador de comparación de igualdad trabajará con operandos de diferentes tipos si existe una conversión implícita de uno a otro. Si no existe una conversión implícita adecuada, puede llamar a una conversión explícita o usar un método para convertir a un tipo compatible.
1 == 1.0 // Returns true because there is an implicit cast from int to double.
new Object() == 1.0 // Will not compile.
MyStruct.AsInt() == 1 // Calls AsInt() on MyStruct and compares the resulting int with 1.
A diferencia de Visual Basic.NET, el operador de comparación de igualdad no es el mismo que el operador de asignación de igualdad.
var x = new Object();
var y = new Object();
x == y // Returns false, the operands (objects in this case) have different references.
x == x // Returns true, both operands have the same reference.
No debe confundirse con el operador de asignación ( =
).
Para los tipos de valor, el operador devuelve true
si ambos operandos tienen el mismo valor.
Para los tipos de referencia, el operador devuelve true
si ambos operandos son iguales en referencia (no en valor). Una excepción es que los objetos de cadena se compararán con la igualdad de valores.
No es igual
Comprueba si los operandos suministrados no son iguales.
"a" != "b" // Returns true.
"a" != "a" // Returns false.
1 != 0 // Returns true.
1 != 1 // Returns false.
false != true // Returns true.
false != false // Returns false.
var x = new Object();
var y = new Object();
x != y // Returns true, the operands have different references.
x != x // Returns false, both operands have the same reference.
Este operador devuelve efectivamente el resultado opuesto al del operador igual ( ==
)
Mas grande que
Comprueba si el primer operando es mayor que el segundo operando.
3 > 5 //Returns false.
1 > 0 //Returns true.
2 > 2 //Return false.
var x = 10;
var y = 15;
x > y //Returns false.
y > x //Returns true.
Menos que
Comprueba si el primer operando es menor que el segundo operando.
2 < 4 //Returns true.
1 < -3 //Returns false.
2 < 2 //Return false.
var x = 12;
var y = 22;
x < y //Returns true.
y < x //Returns false.
Mayor que igual a
Comprueba si el primer operando es mayor que igual al segundo operando.
7 >= 8 //Returns false.
0 >= 0 //Returns true.
Menos que igual a
Comprueba si el primer operando es menor que igual al segundo operando.
2 <= 4 //Returns true.
1 <= -3 //Returns false.
1 <= 1 //Returns true.
Operadores de cortocircuito
Por definición, los operadores booleanos de cortocircuito solo evaluarán el segundo operando si el primer operando no puede determinar el resultado general de la expresión.
Significa que, si está utilizando && operator como firstCondition && secondCondition , evaluará secondCondition solo cuando firstCondition sea verdadero y, por lo tanto, el resultado general será verdadero solo si tanto firstOperand como secondOperand se evalúan como verdaderos. Esto es útil en muchos escenarios, por ejemplo, imagine que desea verificar mientras que su lista tiene más de tres elementos, pero también debe verificar si la lista se ha inicializado para no ejecutarse en NullReferenceException . Puedes lograr esto de la siguiente manera:
bool hasMoreThanThreeElements = myList != null && mList.Count > 3;
mList.Count> 3 no se verificará hasta que se cumpla myList! = null.
Y lógico
&&
es la contraparte de cortocircuito del operador booleano AND ( &
).
var x = true;
var y = false;
x && x // Returns true.
x && y // Returns false (y is evaluated).
y && x // Returns false (x is not evaluated).
y && y // Returns false (right y is not evaluated).
O lógico
||
es la contraparte de cortocircuito del operador booleano OR ( |
).
var x = true;
var y = false;
x || x // Returns true (right x is not evaluated).
x || y // Returns true (y is not evaluated).
y || x // Returns true (x and y are evaluated).
y || y // Returns false (y and y are evaluated).
Ejemplo de uso
if(object != null && object.Property)
// object.Property is never accessed if object is null, because of the short circuit.
Action1();
else
Action2();
tamaño de
Devuelve un int
contiene el tamaño de un tipo * en bytes.
sizeof(bool) // Returns 1.
sizeof(byte) // Returns 1.
sizeof(sbyte) // Returns 1.
sizeof(char) // Returns 2.
sizeof(short) // Returns 2.
sizeof(ushort) // Returns 2.
sizeof(int) // Returns 4.
sizeof(uint) // Returns 4.
sizeof(float) // Returns 4.
sizeof(long) // Returns 8.
sizeof(ulong) // Returns 8.
sizeof(double) // Returns 8.
sizeof(decimal) // Returns 16.
* Solo soporta ciertos tipos primitivos en contexto seguro.
En un contexto inseguro, sizeof
puede usarse para devolver el tamaño de otros tipos y estructuras primitivas.
public struct CustomType
{
public int value;
}
static void Main()
{
unsafe
{
Console.WriteLine(sizeof(CustomType)); // outputs: 4
}
}
Sobrecarga de operadores de igualdad.
Sobrecargar solo a los operadores de igualdad no es suficiente. Bajo diferentes circunstancias, todo lo siguiente puede ser llamado:
-
object.Equals
andobject.GetHashCode
-
IEquatable<T>.Equals
(opcional, permite evitar el boxeo) -
operator ==
yoperator !=
(opcional, permite usar operadores)
Cuando se reemplaza Equals
, GetHashCode
también debe ser overriden. Cuando se implementa Equals
, hay muchos casos especiales: comparando con objetos de un tipo diferente, comparándose con uno mismo, etc.
Cuando NO se reemplaza, el método de Equals
y el operador ==
comportan de manera diferente para las clases y estructuras. Para las clases, solo se comparan las referencias, y para las estructuras, los valores de las propiedades se comparan a través de la reflexión, lo que puede afectar negativamente el rendimiento. ==
no se puede usar para comparar estructuras a menos que esté anulado.
Generalmente la operación de igualdad debe obedecer las siguientes reglas:
- No debe lanzar excepciones .
- Reflexividad:
A
siempre es igual aA
(puede no ser cierto para valoresNULL
en algunos sistemas). - Transitvity: si
A
es igual aB
, yB
es igual aC
, entoncesA
es igual aC
- Si
A
es igual aB
, entoncesA
yB
tienen códigos hash iguales. - Independencia del árbol de herencia: si
B
yC
son instancias deClass2
heredadas deClass1
:Class1.Equals(A,B)
siempre deben devolver el mismo valor que la llamada aClass2.Equals(A,B)
.
class Student : IEquatable<Student>
{
public string Name { get; set; } = "";
public bool Equals(Student other)
{
if (ReferenceEquals(other, null)) return false;
if (ReferenceEquals(other, this)) return true;
return string.Equals(Name, other.Name);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
return Equals(obj as Student);
}
public override int GetHashCode()
{
return Name?.GetHashCode() ?? 0;
}
public static bool operator ==(Student left, Student right)
{
return Equals(left, right);
}
public static bool operator !=(Student left, Student right)
{
return !Equals(left, right);
}
}
Operadores de Miembros de Clase: Acceso de Miembros
var now = DateTime.UtcNow;
//accesses member of a class. In this case the UtcNow property.
Operadores de miembros de clase: Acceso de miembro condicional nulo
var zipcode = myEmployee?.Address?.ZipCode;
//returns null if the left operand is null.
//the above is the equivalent of:
var zipcode = (string)null;
if (myEmployee != null && myEmployee.Address != null)
zipcode = myEmployee.Address.ZipCode;
Operadores de Miembros de Clase: Invocación de Función
var age = GetAge(dateOfBirth);
//the above calls the function GetAge passing parameter dateOfBirth.
Operadores de Miembros de Clase: Indización de Objetos Agregados
var letters = "letters".ToCharArray();
char letter = letters[1];
Console.WriteLine("Second Letter is {0}",letter);
//in the above example we take the second character from the array
//by calling letters[1]
//NB: Array Indexing starts at 0; i.e. the first letter would be given by letters[0].
Operadores de Miembros de Clase: Indización Condicional Nula
var letters = null;
char? letter = letters?[1];
Console.WriteLine("Second Letter is {0}",letter);
//in the above example rather than throwing an error because letters is null
//letter is assigned the value null
"Exclusivo o" Operador
El operador para un "exclusivo o" (para XOR corto) es: ^
Este operador devuelve verdadero cuando uno, pero solo uno, de los valores proporcionados son verdaderos.
true ^ false // Returns true
false ^ true // Returns true
false ^ false // Returns false
true ^ true // Returns false
Operadores de cambio de bits
Los operadores de cambio permiten a los programadores ajustar un número entero desplazando todos sus bits hacia la izquierda o hacia la derecha. El siguiente diagrama muestra el efecto de desplazar un valor a la izquierda en un dígito.
Shift izquierdo
uint value = 15; // 00001111
uint doubled = value << 1; // Result = 00011110 = 30
uint shiftFour = value << 4; // Result = 11110000 = 240
Giro a la derecha
uint value = 240; // 11110000
uint halved = value >> 1; // Result = 01111000 = 120
uint shiftFour = value >> 4; // Result = 00001111 = 15
Operadores de fundición implícita y explícita
C # permite que los tipos definidos por el usuario controlen la asignación y la conversión mediante el uso de palabras clave explicit
e implicit
. La firma del método toma la forma:
public static <implicit/explicit> operator <ResultingType>(<SourceType> myType)
El método no puede tomar más argumentos, ni puede ser un método de instancia. Sin embargo, puede acceder a cualquier miembro privado del tipo dentro del cual esté definido.
Un ejemplo de un reparto implicit
y explicit
:
public class BinaryImage
{
private bool[] _pixels;
public static implicit operator ColorImage(BinaryImage im)
{
return new ColorImage(im);
}
public static explicit operator bool[](BinaryImage im)
{
return im._pixels;
}
}
Permitiendo la siguiente sintaxis de reparto:
var binaryImage = new BinaryImage();
ColorImage colorImage = binaryImage; // implicit cast, note the lack of type
bool[] pixels = (bool[])binaryImage; // explicit cast, defining the type
Los operadores de cast pueden trabajar en ambos sentidos, yendo desde su tipo hasta su tipo:
public class BinaryImage
{
public static explicit operator ColorImage(BinaryImage im)
{
return new ColorImage(im);
}
public static explicit operator BinaryImage(ColorImage cm)
{
return new BinaryImage(cm);
}
}
Finalmente, la palabra clave as
, que puede participar en la conversión dentro de una jerarquía de tipos, no es válida en esta situación. Incluso después de definir una explicit
o implicit
, no puede hacer:
ColorImage cm = myBinaryImage as ColorImage;
Se generará un error de compilación.
Operadores binarios con asignación
C # tiene varios operadores que se pueden combinar con un signo =
para evaluar el resultado del operador y luego asignar el resultado a la variable original.
Ejemplo:
x += y
es lo mismo que
x = x + y
Operadores de Asignación:
-
+=
-
-=
-
*=
-
/=
-
%=
-
&=
-
|=
-
^=
-
<<=
-
>>=
? : Operador Ternario
Devuelve uno de los dos valores dependiendo del valor de una expresión booleana.
Sintaxis:
condition ? expression_if_true : expression_if_false;
Ejemplo:
string name = "Frank";
Console.WriteLine(name == "Frank" ? "The name is Frank" : "The name is not Frank");
El operador ternario es asociativo a la derecha, lo que permite utilizar expresiones ternarias compuestas. Esto se hace agregando ecuaciones ternarias adicionales en la posición verdadera o falsa de una ecuación ternaria principal. Se debe tener cuidado para garantizar la legibilidad, pero esto puede ser un atajo útil en algunas circunstancias.
En este ejemplo, una operación ternaria compuesta evalúa una función de clamp
y devuelve el valor actual si está dentro del rango, el valor min
si está por debajo del rango o el valor max
si está por encima del rango.
light.intensity = Clamp(light.intensity, minLight, maxLight);
public static float Clamp(float val, float min, float max)
{
return (val < min) ? min : (val > max) ? max : val;
}
Los operadores ternarios también pueden estar anidados, como:
a ? b ? "a is true, b is true" : "a is true, b is false" : "a is false"
// This is evaluated from left to right and can be more easily seen with parenthesis:
a ? (b ? x : y) : z
// Where the result is x if a && b, y if a && !b, and z if !a
Al escribir declaraciones ternarias compuestas, es común usar paréntesis o sangría para mejorar la legibilidad.
Los tipos de expresión_if_true y expresión_if_false deben ser idénticos o debe haber una conversión implícita de uno a otro.
condition ? 3 : "Not three"; // Doesn't compile because `int` and `string` lack an implicit conversion.
condition ? 3.ToString() : "Not three"; // OK because both possible outputs are strings.
condition ? 3 : 3.5; // OK because there is an implicit conversion from `int` to `double`. The ternary operator will return a `double`.
condition ? 3.5 : 3; // OK because there is an implicit conversion from `int` to `double`. The ternary operator will return a `double`.
Los requisitos de tipo y conversión se aplican a sus propias clases también.
public class Car
{}
public class SportsCar : Car
{}
public class SUV : Car
{}
condition ? new SportsCar() : new Car(); // OK because there is an implicit conversion from `SportsCar` to `Car`. The ternary operator will return a reference of type `Car`.
condition ? new Car() : new SportsCar(); // OK because there is an implicit conversion from `SportsCar` to `Car`. The ternary operator will return a reference of type `Car`.
condition ? new SportsCar() : new SUV(); // Doesn't compile because there is no implicit conversion from `SportsCar` to SUV or `SUV` to `SportsCar`. The compiler is not smart enough to realize that both of them have an implicit conversion to `Car`.
condition ? new SportsCar() as Car : new SUV() as Car; // OK because both expressions evaluate to a reference of type `Car`. The ternary operator will return a reference of type `Car`.
tipo de
Obtiene el objeto System.Type
para un tipo.
System.Type type = typeof(Point) //System.Drawing.Point
System.Type type = typeof(IDisposable) //System.IDisposable
System.Type type = typeof(Colors) //System.Drawing.Color
System.Type type = typeof(List<>) //System.Collections.Generic.List`1[T]
Para obtener el tipo de tiempo de ejecución, utilice GetType
método para obtener el System.Type
de la instancia actual.
Operador typeof
toma un nombre de tipo como parámetro, que se especifica en tiempo de compilación.
public class Animal {}
public class Dog : Animal {}
var animal = new Dog();
Assert.IsTrue(animal.GetType() == typeof(Animal)); // fail, animal is typeof(Dog)
Assert.IsTrue(animal.GetType() == typeof(Dog)); // pass, animal is typeof(Dog)
Assert.IsTrue(animal is Animal); // pass, animal implements Animal
operador predeterminado
Tipo de valor (donde T: struct)
Los tipos de datos primitivos incorporados, como char
, int
y float
, así como los tipos definidos por el usuario declarados con struct
o enum
. Su valor predeterminado es new T()
:
default(int) // 0
default(DateTime) // 0001-01-01 12:00:00 AM
default(char) // '\0' This is the "null character", not a zero or a line break.
default(Guid) // 00000000-0000-0000-0000-000000000000
default(MyStruct) // new MyStruct()
// Note: default of an enum is 0, and not the first *key* in that enum
// so it could potentially fail the Enum.IsDefined test
default(MyEnum) // (MyEnum)0
Tipo de referencia (donde T: clase)
Cualquier class
, interface
, matriz o tipo delegado. Su valor predeterminado es null
:
default(object) // null
default(string) // null
default(MyClass) // null
default(IDisposable) // null
default(dynamic) // null
Nombre del operador
Devuelve una cadena que representa el nombre no calificado de una variable
, type
o member
.
int counter = 10;
nameof(counter); // Returns "counter"
Client client = new Client();
nameof(client.Address.PostalCode)); // Returns "PostalCode"
El operador nameof
fue introducido en C # 6.0. Se evalúa en tiempo de compilación y el compilador inserta el valor de cadena devuelto en línea, por lo que puede usarse en la mayoría de los casos donde se puede usar la cadena constante (por ejemplo, las etiquetas de case
en una declaración de switch
, atributos, etc.) .). Puede ser útil en casos como generar y registrar excepciones, atributos, enlaces de acción de MVC, etc.
?. (Operador Condicional Nulo)
Introducido en C # 6.0 , ¿el operador condicional nulo ?.
devolverá inmediatamente null
si la expresión en su lado izquierdo se evalúa como null
, en lugar de lanzar una NullReferenceException
. Si su lado izquierdo se evalúa como un valor no null
, se trata como un normal .
operador. Tenga en cuenta que debido a que puede devolver un null
, su tipo de retorno siempre es un tipo que puede contener null
. Eso significa que para una estructura o tipo primitivo, se envuelve en un Nullable<T>
.
var bar = Foo.GetBar()?.Value; // will return null if GetBar() returns null
var baz = Foo.GetBar()?.IntegerValue; // baz will be of type Nullable<int>, i.e. int?
Esto es útil cuando se disparan eventos. Normalmente, tendría que ajustar la llamada de evento en una sentencia if que compruebe si es null
y luego elevar el evento, lo que presenta la posibilidad de una condición de carrera. Usando el operador condicional nulo, esto se puede arreglar de la siguiente manera:
event EventHandler<string> RaiseMe;
RaiseMe?.Invoke("Event raised");
Postfix y Prefijo incremento y decremento
El incremento de Postfix X++
agregará 1
a x
var x = 42;
x++;
Console.WriteLine(x); // 43
X--
Postfix X--
restará uno
var x = 42
x--;
Console.WriteLine(x); // 41
++x
se denomina incremento de prefijo, incrementa el valor de x y luego devuelve x mientras que x++
devuelve el valor de x y luego incrementa
var x = 42;
Console.WriteLine(++x); // 43
System.out.println(x); // 43
mientras
var x = 42;
Console.WriteLine(x++); // 42
System.out.println(x); // 43
Ambos se utilizan comúnmente en bucle for
for(int i = 0; i < 10; i++)
{
}
=> Operador Lambda
El operador =>
tiene la misma precedencia que el operador de asignación =
y es asociativo a la derecha.
Se utiliza para declarar expresiones lambda y también se usa ampliamente con las consultas LINQ :
string[] words = { "cherry", "apple", "blueberry" };
int shortestWordLength = words.Min((string w) => w.Length); //5
Cuando se usa en las consultas o extensiones de LINQ, el tipo de los objetos generalmente se puede omitir como lo deduce el compilador:
int shortestWordLength = words.Min(w => w.Length); //also compiles with the same result
La forma general de operador lambda es la siguiente:
(input parameters) => expression
Los parámetros de la expresión lambda se especifican antes del operador =>
, y la expresión / declaración / bloque real que se ejecutará está a la derecha del operador:
// expression
(int x, string s) => s.Length > x
// expression
(int x, int y) => x + y
// statement
(string x) => Console.WriteLine(x)
// block
(string x) => {
x += " says Hello!";
Console.WriteLine(x);
}
Este operador se puede usar para definir fácilmente delegados, sin escribir un método explícito:
delegate void TestDelegate(string s);
TestDelegate myDelegate = s => Console.WriteLine(s + " World");
myDelegate("Hello");
en lugar de
void MyMethod(string s)
{
Console.WriteLine(s + " World");
}
delegate void TestDelegate(string s);
TestDelegate myDelegate = MyMethod;
myDelegate("Hello");
Operador de asignación '='
El operador de asignación =
establece el valor del operando de la mano izquierda al valor del operando de la derecha y devuelve ese valor:
int a = 3; // assigns value 3 to variable a
int b = a = 5; // first assigns value 5 to variable a, then does the same for variable b
Console.WriteLine(a = 3 + 4); // prints 7
?? Operador de unión nula
¿El operador nulo-coalescente ??
devolverá el lado izquierdo cuando no sea nulo. Si es nulo, devolverá el lado derecho.
object foo = null;
object bar = new object();
var c = foo ?? bar;
//c will be bar since foo was null
El ??
El operador puede ser encadenado lo que permite la eliminación de if
cheques.
//config will be the first non-null returned.
var config = RetrieveConfigOnMachine() ??
RetrieveConfigFromService() ??
new DefaultConfiguration();