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 tipo T
    • typeof - Restituisce l'oggetto Type 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 - Restituisce x .
    • -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 un Task .
    • &x - Restituisce l'indirizzo (puntatore) di x .
    • *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 - Restituisce x se non è nullo; altrimenti, restituisce y .
  • Operatore condizionale

    • x ? y : z - Valuta / restituisce y se x è vero; altrimenti, valuta z .

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) .

7.0

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:

  1. object.Equals e object.GetHashCode
  2. IEquatable<T>.Equals (facoltativo, consente di evitare la boxe)
  3. operator == e operator != (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 a A (potrebbe non essere vero per i valori NULL in alcuni sistemi).
  • Transitvity: se A uguale a B , e B uguale a C , allora A uguale a C
  • Se A uguale a B , allora A e B hanno uguali codici hash.
  • Indipendenza dell'albero di successione: se B e C sono istanze di Class2 ereditate da Class1 : Class1.Equals(A,B) deve sempre restituire lo stesso valore della chiamata a Class2.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)

6.0

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

3.0

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();


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow