C# Language
operatori
Ricerca…
introduzione
In C #, un operatore è un elemento di programma che viene applicato a uno o più operandi in un'espressione o istruzione. Gli operatori che accettano un operando, come l'operatore di incremento (++) o nuovo, sono indicati come operatori unari. Gli operatori che accettano due operandi, come gli operatori aritmetici (+, -, *, /), sono indicati come operatori binari. Un operatore, l'operatore condizionale (? :), prende tre operandi ed è l'unico operatore ternario in C #.
Sintassi
- operatore statico pubblico OperandType operatoreSymbol (OperandType operando1)
- operatore statico pubblico OperandType operatoreSymbol (OperandType operand1, OperandType2 operando2)
Parametri
Parametro | Dettagli |
---|---|
operatorSymbol | Sovraccarico dell'operatore, ad es. +, -, /, * |
OperandType | Il tipo che verrà restituito dall'operatore sovraccarico. |
operand1 | Il primo operando da utilizzare nell'esecuzione dell'operazione. |
operando2 | Il secondo operando da utilizzare nell'esecuzione dell'operazione, quando si eseguono operazioni binarie. |
dichiarazioni | Codice opzionale necessario per eseguire l'operazione prima di restituire il risultato. |
Osservazioni
Tutti gli operatori sono definiti come static methods
e non sono virtual
e non vengono ereditati.
Precedenza dell'operatore
Tutti gli operatori hanno una "precedenza" particolare a seconda del gruppo in cui ricade l'operatore (gli operatori dello stesso gruppo hanno la stessa priorità). Significa che alcuni operatori saranno applicati prima degli altri. Quello che segue è un elenco di gruppi (contenenti i rispettivi operatori) ordinati per precedenza (prima i più alti):
Operatori primari
-
ab
- Accesso membri. -
a?.b
- Accesso ai membri condizionali Null. -
->
- Dereferencing del puntatore combinato con l'accesso dei membri. -
f(x)
- Richiamo funzione. -
a[x]
- Indicizzatore. -
a?[x]
- Indicatore condizionale nullo. -
x++
- Incremento postfisso. -
x--
-x--
Postfix. -
new
- Digitare l'istanza. -
default(T)
- Restituisce il valore inizializzato predefinito di tipoT
-
typeof
- Restituisce l'oggettoType
dell'operando. -
checked
: abilita il controllo di overflow numerico. -
unchecked
: disattiva il controllo di overflow numerico. -
delegate
- Dichiara e restituisce un'istanza delegata. -
sizeof
- Restituisce la dimensione in byte dell'operando di tipo.
-
Operatori unari
-
+x
- Restituiscex
. -
-x
- Negazione numerica. -
!x
- Negazione logica. -
~x
- Complemento bit per bit / dichiara i distruttori. -
++x
- Incremento del prefisso. -
--x
---x
prefisso. -
(T)x
- Tipologia casting. -
await
- Aspetta unTask
. -
&x
- Restituisce l'indirizzo (puntatore) dix
. -
*x
- Dereferenziamento puntatore.
-
Operatori moltiplicativi
-
x * y
- Moltiplicazione. -
x / y
- Divisione. -
x % y
- Modulo.
-
Operatori additivi
-
x + y
- Aggiunta. -
x – y
- sottrazione.
-
Operatori di spostamento bit a bit
-
x << y
- Maiuscole a sinistra. -
x >> y
- Maiuscole a destra.
-
Operatori di test di tipo / relazionale
-
x < y
- Meno di. -
x > y
- Maggiore di. -
x <= y
- Minore o uguale a. -
x >= y
- Maggiore o uguale a. -
is
- Digitare la compatibilità. -
as
- Conversione di tipo.
-
Operatori di uguaglianza
-
x == y
- Uguaglianza. -
x != y
- Non uguale.
-
Logico E Operatore
-
x & y
- Logico / bit a bit AND.
-
Operatore logico XOR
-
x ^ y
- XOR logico / bit a bit.
-
Logico O Operatore
-
x | y
- OR logico / bit a bit.
-
Condizionale E Operatore
-
x && y
- Cortocircuito AND logico.
-
Operatore OR condizionale
-
x || y
- Cortocircuito logico OR.
-
Operatore a coalescenza nulla
-
x ?? y
- Restituiscex
se non è nullo; altrimenti, restituiscey
.
-
Operatore condizionale
-
x ? y : z
- Valuta / restituiscey
sex
è vero; altrimenti, valutaz
.
-
Contenuto relativo
Operatori sovraccarichi
C # consente ai tipi definiti dall'utente di sovraccaricare gli operatori definendo funzioni membro statiche utilizzando la parola chiave operator
.
L'esempio seguente illustra un'implementazione dell'operatore +
.
Se abbiamo una classe Complex
che rappresenta un numero complesso:
public struct Complex
{
public double Real { get; set; }
public double Imaginary { get; set; }
}
E vogliamo aggiungere l'opzione per usare l'operatore +
per questa classe. vale a dire:
Complex a = new Complex() { Real = 1, Imaginary = 2 };
Complex b = new Complex() { Real = 4, Imaginary = 8 };
Complex c = a + b;
Dovremo sovraccaricare l'operatore +
per la classe. Questo viene fatto usando una funzione statica e la parola chiave operator
:
public static Complex operator +(Complex c1, Complex c2)
{
return new Complex
{
Real = c1.Real + c2.Real,
Imaginary = c1.Imaginary + c2.Imaginary
};
}
Operatori come +
, -
, *
, /
possono essere sovraccaricati. Ciò include anche operatori che non restituiscono lo stesso tipo (ad esempio, ==
e !=
Possono essere sovraccaricati, nonostante il ritorno di booleani) Viene applicata anche la regola seguente relativa alle coppie.
Gli operatori di confronto devono essere sovraccaricati a coppie (ad esempio, se <
è sovraccarico, >
deve essere sovraccaricato).
Un elenco completo degli operatori sovraccaricabili (così come degli operatori non sovraccaricabili e delle restrizioni imposte ad alcuni operatori sovraccaricabili) può essere visto su MSDN - Operatori sovraccaricabili (C # Programming Guide) .
l'overloading operator is
stato introdotto con il meccanismo di corrispondenza del modello di C # 7.0. Per i dettagli vedi Pattern Matching
Dato un tipo di Cartesian
definito come segue
public class Cartesian
{
public int X { get; }
public int Y { get; }
}
Un operator is
sovraccarico può essere definito ad esempio per coordinate 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;
}
}
che può essere usato in questo modo
var c = Cartesian(3, 4);
if (c is Polar(var R, *))
{
Console.WriteLine(R);
}
(L'esempio è tratto dalla documentazione di corrispondenza del modello Roslyn )
Operatori relazionali
È uguale a
Controlla se gli operandi forniti (argomenti) sono uguali
"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 differenza di Java, l'operatore di confronto delle uguaglianze funziona in modo nativo con le stringhe.
L'operatore di confronto di uguaglianza funzionerà con operandi di tipi diversi se esiste un cast implicito da uno all'altro. Se non esiste alcun cast implicito adatto, è possibile chiamare un cast esplicito o utilizzare un metodo per convertire in un tipo compatibile.
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 differenza di Visual Basic.NET, l'operatore di confronto delle uguaglianze non è uguale all'operatore di assegnazione dell'uguaglianza.
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.
Da non confondere con l'operatore di assegnazione ( =
).
Per i tipi di valore, l'operatore restituisce true
se entrambi gli operandi hanno valore uguale.
Per i tipi di riferimento, l'operatore restituisce true
se entrambi gli operandi sono uguali in riferimento (non valore). Un'eccezione è che gli oggetti stringa saranno confrontati con l'uguaglianza dei valori.
Non uguale
Controlla se gli operandi forniti non sono uguali.
"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.
Questo operatore restituisce in modo efficace il risultato opposto a quello dell'operatore di uguale ( ==
)
Più grande di
Controlla se il primo operando è maggiore del secondo 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.
Meno di
Controlla se il primo operando è inferiore al secondo 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.
Maggiore di uguale a
Controlla se il primo operando è maggiore di uguale al secondo operando.
7 >= 8 //Returns false.
0 >= 0 //Returns true.
Meno di uguale a
Controlla se il primo operando è inferiore al secondo operando.
2 <= 4 //Returns true.
1 <= -3 //Returns false.
1 <= 1 //Returns true.
Operatori di cortocircuito
Per definizione, gli operatori booleani di cortocircuito valuteranno solo il secondo operando se il primo operando non è in grado di determinare il risultato complessivo dell'espressione.
Significa che, se si utilizza && operator come firstCondition e& secondCondition , verrà valutata secondCondition solo quando firstCondition è true e ofcource il risultato complessivo sarà true solo se entrambi di firstOperand e secondOperand vengono valutati su true. Questo è utile in molti scenari, ad esempio immagina di voler controllare mentre il tuo elenco ha più di tre elementi ma devi anche controllare se l'elenco è stato inizializzato per non essere eseguito in NullReferenceException . Puoi ottenerlo come di seguito:
bool hasMoreThanThreeElements = myList != null && mList.Count > 3;
mList.Count> 3 non verrà controllato fino a myList! = null è soddisfatto.
AND logico
&&
è la controparte in cortocircuito dell'operatore AND ( &
) standard booleano.
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).
OR logico
||
è la controparte in cortocircuito dell'operatore standard 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).
Esempio di utilizzo
if(object != null && object.Property)
// object.Property is never accessed if object is null, because of the short circuit.
Action1();
else
Action2();
taglia di
Restituisce un int
che int
la dimensione di un tipo * in byte.
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.
* Supporta solo alcuni tipi primitivi in un contesto sicuro.
In un contesto non sicuro, sizeof
può essere utilizzato per restituire la dimensione di altri tipi e strutture primitive.
public struct CustomType
{
public int value;
}
static void Main()
{
unsafe
{
Console.WriteLine(sizeof(CustomType)); // outputs: 4
}
}
Sovraccarico di operatori di uguaglianza
Sovraccaricare solo gli operatori di uguaglianza non è sufficiente. In diverse circostanze, è possibile chiamare tutti i seguenti:
-
object.Equals
eobject.GetHashCode
-
IEquatable<T>.Equals
(facoltativo, consente di evitare la boxe) -
operator ==
eoperator !=
(facoltativo, consente di utilizzare gli operatori)
Quando si Equals
override di Equals
, anche GetHashCode
deve essere sostituito. Quando si implementa Equals
, ci sono molti casi speciali: confronto con oggetti di un tipo diverso, confronto con il sé ecc.
Quando NON viene sovrascritto il metodo Equals
e l'operatore ==
comportano diversamente per le classi e le strutture. Per le classi vengono confrontati solo i riferimenti e per i valori delle strutture le proprietà vengono confrontate tramite la riflessione, cosa può influire negativamente sulle prestazioni. ==
non può essere usato per confrontare le strutture a meno che non sia sovrascritto.
Generalmente l'operazione di uguaglianza deve rispettare le seguenti regole:
- Non deve generare eccezioni .
- Reflexivity:
A
sempre uguale aA
(potrebbe non essere vero per i valoriNULL
in alcuni sistemi). - Transitvity: se
A
uguale aB
, eB
uguale aC
, alloraA
uguale aC
- Se
A
uguale aB
, alloraA
eB
hanno uguali codici hash. - Indipendenza dell'albero di successione: se
B
eC
sono istanze diClass2
ereditate daClass1
:Class1.Equals(A,B)
deve sempre restituire lo stesso valore della chiamata 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);
}
}
Operatori membri della classe: accesso membri
var now = DateTime.UtcNow;
//accesses member of a class. In this case the UtcNow property.
Operatori membri della classe: accesso con membri condizionali nulli
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;
Operatori membri della classe: chiamata funzione
var age = GetAge(dateOfBirth);
//the above calls the function GetAge passing parameter dateOfBirth.
Operatori membri della classe: indicizzazione degli oggetti aggregati
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].
Operatori membri della classe: indicizzazione condizionale nullo
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
"Esclusivo o" Operatore
L'operatore per un "esclusivo o" (per XOR breve) è: ^
Questo operatore restituisce true quando uno, ma solo uno, dei bool forniti è vero.
true ^ false // Returns true
false ^ true // Returns true
false ^ false // Returns false
true ^ true // Returns false
Operatori Bit-Shifting
Gli operatori di spostamento consentono ai programmatori di regolare un numero intero spostando tutti i suoi bit a sinistra o a destra. Il seguente diagramma mostra l'effetto di spostare un valore a sinistra di una cifra.
Tasto maiuscolo di sinistra
uint value = 15; // 00001111
uint doubled = value << 1; // Result = 00011110 = 30
uint shiftFour = value << 4; // Result = 11110000 = 240
Destra-Shift
uint value = 240; // 11110000
uint halved = value >> 1; // Result = 01111000 = 120
uint shiftFour = value >> 4; // Result = 00001111 = 15
Operatori di cast impliciti ed espliciti
C # consente ai tipi definiti dall'utente di controllare l'assegnazione e il cast attraverso l'uso di parole chiave explicit
e implicit
. La firma del metodo assume la forma:
public static <implicit/explicit> operator <ResultingType>(<SourceType> myType)
Il metodo non può accettare altri argomenti, né può essere un metodo di istanza. Può, tuttavia, accedere a qualsiasi membro privato di tipo in cui è definito.
Un esempio di un cast implicit
ed 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;
}
}
Consentire la seguente sintassi del cast:
var binaryImage = new BinaryImage();
ColorImage colorImage = binaryImage; // implicit cast, note the lack of type
bool[] pixels = (bool[])binaryImage; // explicit cast, defining the type
Gli operatori del cast possono lavorare in entrambe le direzioni, andando dal tuo tipo e andando al tuo 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);
}
}
Infine, la parola chiave as
, che può essere coinvolta nel cast all'interno di una gerarchia di tipi, non è valida in questa situazione. Anche dopo aver definito un cast explicit
o implicit
, non puoi fare:
ColorImage cm = myBinaryImage as ColorImage;
Genererà un errore di compilazione.
Operatori binari con assegnazione
C # ha diversi operatori che possono essere combinati con un segno =
per valutare il risultato dell'operatore e quindi assegnare il risultato alla variabile originale.
Esempio:
x += y
equivale a
x = x + y
Operatori di assegnazione:
-
+=
-
-=
-
*=
-
/=
-
%=
-
&=
-
|=
-
^=
-
<<=
-
>>=
? : Operatore ternario
Restituisce uno dei due valori in base al valore di un'espressione booleana.
Sintassi:
condition ? expression_if_true : expression_if_false;
Esempio:
string name = "Frank";
Console.WriteLine(name == "Frank" ? "The name is Frank" : "The name is not Frank");
L'operatore ternario ha una associazione destra che consente di utilizzare espressioni ternarie composte. Questo viene fatto aggiungendo ulteriori equazioni ternarie nella posizione vera o falsa di un'equazione ternaria genitore. Bisogna fare attenzione per garantire la leggibilità, ma questa può essere una utile stenografia in alcune circostanze.
In questo esempio, un'operazione ternaria composta valuta una funzione di clamp
e restituisce il valore corrente se è compreso nell'intervallo, il valore min
se è inferiore all'intervallo o il valore max
se è superiore all'intervallo.
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;
}
Anche gli operatori ternari possono essere annidati, come ad esempio:
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
Quando si scrivono dichiarazioni ternarie composte, è comune utilizzare parentesi o rientranza per migliorare la leggibilità.
I tipi di expression_if_true e expression_if_false devono essere identici o deve esserci una conversione implicita da uno all'altro.
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`.
I requisiti di tipo e conversione si applicano anche alle tue classi.
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 di
Ottiene l'oggetto System.Type
per 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]
Per ottenere il tipo di runtime, utilizzare il metodo GetType
per ottenere System.Type
dell'istanza corrente.
L'operatore typeof
accetta un nome di tipo come parametro, che viene specificato al momento della compilazione.
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
Operatore predefinito
Tipo di valore (dove T: struct)
I tipi di dati primitivi predefiniti, come char
, int
e float
, nonché i tipi definiti dall'utente dichiarati con struct
o enum
. Il loro valore predefinito è 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 di riferimento (dove T: classe)
Qualsiasi tipo di class
, interface
, matrice o delegato. Il loro valore predefinito è null
:
default(object) // null
default(string) // null
default(MyClass) // null
default(IDisposable) // null
default(dynamic) // null
nome dell'operatore
Restituisce una stringa che rappresenta il nome non qualificato di una variable
, type
o member
.
int counter = 10;
nameof(counter); // Returns "counter"
Client client = new Client();
nameof(client.Address.PostalCode)); // Returns "PostalCode"
L'operatore nameof
stato introdotto in C # 6.0. Viene valutato in fase di compilazione e il valore stringa restituito viene inserito inline dal compilatore, quindi può essere utilizzato nella maggior parte dei casi in cui è possibile utilizzare la stringa costante (ad esempio, le etichette case
in un'istruzione switch
, attributi, ecc. .). Può essere utile in casi come le eccezioni di sollevamento e registrazione, gli attributi, i link di azione MVC, ecc ...
?. (Operatore condizionale nullo)
Introdotto in C # 6.0 , il Null Conditional Operator ?.
immediatamente restituire null
se l'espressione sul suo lato sinistro restituisce null
, invece di lanciare un NullReferenceException
. Se il suo lato sinistro valuta un valore non null
, viene trattato come un normale .
operatore. Si noti che poiché potrebbe restituire null
, il suo tipo restituito è sempre un tipo nullable. Ciò significa che per una struttura o un tipo primitivo, è racchiuso in 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?
Questo è utile quando si attivano gli eventi. Normalmente dovresti racchiudere la chiamata dell'evento in un'istruzione if che verifica il null
e innalza l'evento in seguito, che introduce la possibilità di una race condition. Utilizzando l'operatore condizionale Null, questo può essere risolto nel seguente modo:
event EventHandler<string> RaiseMe;
RaiseMe?.Invoke("Event raised");
Postfix e prefisso incremento e decremento
L'incremento Postfix X++
aggiungerà 1
a x
var x = 42;
x++;
Console.WriteLine(x); // 43
Il decremento di Postfix X--
ne sottrarrà uno
var x = 42
x--;
Console.WriteLine(x); // 41
++x
è chiamato incremento prefisso incrementa il valore di x e quindi restituisce x mentre x++
restituisce il valore di x e quindi incrementi
var x = 42;
Console.WriteLine(++x); // 43
System.out.println(x); // 43
mentre
var x = 42;
Console.WriteLine(x++); // 42
System.out.println(x); // 43
entrambi sono comunemente usati in loop
for(int i = 0; i < 10; i++)
{
}
=> Operatore Lambda
L'operatore =>
ha la stessa precedenza dell'operatore di assegnazione =
ed è associato a destra.
Viene utilizzato per dichiarare espressioni lambda e inoltre è ampiamente utilizzato con query LINQ :
string[] words = { "cherry", "apple", "blueberry" };
int shortestWordLength = words.Min((string w) => w.Length); //5
Se utilizzato nelle estensioni o nelle query LINQ, il tipo di oggetti può essere saltato in genere poiché viene dedotto dal compilatore:
int shortestWordLength = words.Min(w => w.Length); //also compiles with the same result
La forma generale dell'operatore lambda è la seguente:
(input parameters) => expression
I parametri dell'espressione lambda sono specificati prima =>
operatore e l'espressione / istruzione / blocco effettivo da eseguire è a destra dell'operatore:
// 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);
}
Questo operatore può essere utilizzato per definire facilmente i delegati, senza scrivere un metodo esplicito:
delegate void TestDelegate(string s);
TestDelegate myDelegate = s => Console.WriteLine(s + " World");
myDelegate("Hello");
invece di
void MyMethod(string s)
{
Console.WriteLine(s + " World");
}
delegate void TestDelegate(string s);
TestDelegate myDelegate = MyMethod;
myDelegate("Hello");
Operatore di assegnazione '='
L'operatore di assegnazione =
imposta il valore dell'operando della mano sinistra al valore dell'operando di destra, e restituisce quel valore:
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
?? Operatore Null Coalescing
L'operatore Null-Coalescing ??
restituirà il lato sinistro quando non è nullo. Se è nullo, restituirà il lato destro.
object foo = null;
object bar = new object();
var c = foo ?? bar;
//c will be bar since foo was null
Il ??
l'operatore può essere incatenato che consente la rimozione di if
controlli.
//config will be the first non-null returned.
var config = RetrieveConfigOnMachine() ??
RetrieveConfigFromService() ??
new DefaultConfiguration();