C# Language
Les opérateurs
Recherche…
Introduction
En C #, un opérateur est un élément de programme appliqué à un ou plusieurs opérandes dans une expression ou une instruction. Les opérateurs qui prennent une opérande, tels que l'opérateur d'incrémentation (++) ou new, sont appelés opérateurs unaires. Les opérateurs qui prennent deux opérandes, tels que les opérateurs arithmétiques (+, -, *, /), sont appelés opérateurs binaires. Un opérateur, l'opérateur conditionnel (? :), prend trois opérandes et est le seul opérateur ternaire en C #.
Syntaxe
- opérateur public OperandType statique operatorSymbol (opérande OperandType1)
- opérateur public OperandType statique operatorSymbol (opérande OperandType1, opérande OperandType22)
Paramètres
Paramètre | Détails |
---|---|
opérateurSymbole | L'opérateur étant surchargé, par exemple +, -, /, * |
OperandType | Le type qui sera renvoyé par l'opérateur surchargé. |
opérande1 | Le premier opérande à utiliser pour effectuer l'opération. |
opérande2 | Le deuxième opérande à utiliser pour effectuer l'opération lors d'opérations binaires. |
déclarations | Code facultatif nécessaire pour effectuer l'opération avant de renvoyer le résultat. |
Remarques
Tous les opérateurs sont définis comme static methods
et ils ne sont pas virtual
et ils ne sont pas hérités.
Priorité de l'opérateur
Tous les opérateurs ont une "priorité" particulière selon le groupe auquel appartient l'opérateur (les opérateurs du même groupe ont la même priorité). Ce qui signifie que certains opérateurs seront appliqués avant les autres. Ce qui suit est une liste de groupes (contenant leurs opérateurs respectifs) classés par priorité (le plus élevé en premier):
Opérateurs Primaires
-
ab
- Accès membre. -
a?.b
- Null accès conditionnel membre. -
->
- Déréférencement du pointeur associé à l'accès des membres. -
f(x)
- invocation de fonction. -
a[x]
- Indexeur. -
a?[x]
- Indexeur conditionnel nul. -
x++
- Incrément Postfix. -
x--
- décrémentationx--
. -
new
- Type instanciation. -
default(T)
- Retourne la valeur initialisée par défaut du typeT
-
typeof
- Retourne l'objetType
de l'opérande. -
checked
- Active la vérification du dépassement numérique. -
unchecked
- Désactive la vérification numérique des dépassements. -
delegate
- Déclare et retourne une instance de délégué. -
sizeof
- Retourne la taille en octets du type opérande.
-
Opérateurs Unaires
-
+x
- Retournex
. -
-x
- Négation numérique. -
!x
- Négation logique. -
~x
- Complément binaire / déclare les destructeurs. -
++x
- Incrément de préfixe. -
--x
- Préfixe décrémenté. -
(T)x
- Type coulée. -
await
- attend uneTask
. -
&x
- Retourne l'adresse (pointeur) dex
. -
*x
- Déréférencement de pointeur.
-
Opérateurs Multiplicatifs
-
x * y
- Multiplication. -
x / y
- Division. -
x % y
- Module.
-
Opérateurs Additifs
-
x + y
- Ajout. -
x – y
- Soustraction.
-
Opérateurs de décalage binaire
-
x << y
- bits de décalage restants. -
x >> y
- Décale les bits à droite.
-
Opérateurs relationnels / tests de type
-
x < y
- moins que. -
x > y
- Supérieur à. -
x <= y
- Inférieur ou égal à. -
x >= y
- supérieur ou égal à. -
is
- Type compatibilité. -
as
- Type conversion.
-
Opérateurs d'égalité
-
x == y
- égalité. -
x != y
- Non égal.
-
Opérateur logique ET
-
x & y
- logique / bit à bit ET.
-
Opérateur logique XOR
-
x ^ y
- Logique / binaire XOR.
-
Opérateur OR logique
-
x | y
- logique / bit à bit OU.
-
Conditionnel ET Opérateur
-
x && y
- ET logique en court-circuit.
-
Opérateur conditionnel
-
x || y
- OU logique en court-circuit.
-
Opérateur de coalescence nulle
-
x ?? y
- Retournex
s'il n'est pas nul; sinon, retourney
.
-
Opérateur conditionnel
-
x ? y : z
- Évalue / retourney
six
est vrai; sinon, évaluez
.
-
Contenu connexe
Opérateurs surchargeables
C # permet aux types définis par l'utilisateur de surcharger les opérateurs en définissant des fonctions membres statiques à l'aide du mot clé operator
.
L'exemple suivant illustre une implémentation de l'opérateur +
.
Si nous avons une classe Complex
qui représente un nombre complexe:
public struct Complex
{
public double Real { get; set; }
public double Imaginary { get; set; }
}
Et nous voulons ajouter l'option permettant d'utiliser l'opérateur +
pour cette classe. c'est à dire:
Complex a = new Complex() { Real = 1, Imaginary = 2 };
Complex b = new Complex() { Real = 4, Imaginary = 8 };
Complex c = a + b;
Nous devrons surcharger l'opérateur +
pour la classe. Ceci est fait en utilisant une fonction statique et le mot-clé d' operator
:
public static Complex operator +(Complex c1, Complex c2)
{
return new Complex
{
Real = c1.Real + c2.Real,
Imaginary = c1.Imaginary + c2.Imaginary
};
}
Les opérateurs tels que +
, -
, *
, /
peuvent tous être surchargés. Cela inclut également les opérateurs qui ne renvoient pas le même type (par exemple, ==
et !=
Peuvent être surchargés, malgré le retour des booléens). La règle ci-dessous relative aux paires est également appliquée ici.
Les opérateurs de comparaison doivent être surchargés par paires (par exemple, si <
est surchargé >
il doit également être surchargé).
Une liste complète des opérateurs surchargeables (ainsi que des opérateurs non surchargeables et des restrictions placées sur certains opérateurs surchargeables) peut être consultée sur MSDN - Overloadable Operators (Guide de programmation C #) .
la surcharge de l' operator is
été introduite avec le mécanisme de correspondance de modèle de C # 7.0. Pour plus de détails, voir Correspondance de motif
Étant donné un type Cartesian
défini comme suit
public class Cartesian
{
public int X { get; }
public int Y { get; }
}
Un operator is
surchargeable peut par exemple être défini pour Polar
coordonnées 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;
}
}
qui peut être utilisé comme ça
var c = Cartesian(3, 4);
if (c is Polar(var R, *))
{
Console.WriteLine(R);
}
(L'exemple est tiré de la documentation Roslyn Pattern Matching Documentation )
Opérateurs relationnels
Équivaut à
Vérifie si les opérandes fournis (arguments) sont égaux
"a" == "b" // Returns false.
"a" == "a" // Returns true.
1 == 0 // Returns false.
1 == 1 // Returns true.
false == true // Returns false.
false == false // Returns true.
Contrairement à Java, l'opérateur de comparaison d'égalité fonctionne en mode natif avec les chaînes.
L'opérateur de comparaison d'égalité fonctionnera avec des opérandes de types différents si une distribution implicite existe de l'un à l'autre. Si aucune distribution implicite appropriée n'existe, vous pouvez appeler une conversion explicite ou utiliser une méthode pour convertir en un type 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.
Contrairement à Visual Basic.NET, l'opérateur de comparaison d'égalité est différent de l'opérateur d'affectation d'égalité.
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.
Ne pas confondre avec l'opérateur d'affectation ( =
).
Pour les types de valeur, l'opérateur renvoie true
si les deux opérandes ont la même valeur.
Pour les types de référence, l'opérateur renvoie true
si les deux opérandes sont égaux en référence (et non en valeur). Une exception est que les objets de chaîne seront comparés avec une égalité de valeur.
Pas égal
Vérifie si les opérandes fournis ne sont pas égaux.
"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.
Cet opérateur renvoie effectivement le résultat opposé à celui de l'opérateur égal ( ==
)
Plus grand que
Vérifie si le premier opérande est supérieur au deuxième opérande.
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.
Moins que
Vérifie si le premier opérande est inférieur au deuxième opérande.
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.
Supérieur à égal à
Vérifie si le premier opérande est supérieur à la seconde opérande.
7 >= 8 //Returns false.
0 >= 0 //Returns true.
Moins que égal à
Vérifie si le premier opérande est inférieur au deuxième opérande.
2 <= 4 //Returns true.
1 <= -3 //Returns false.
1 <= 1 //Returns true.
Opérateurs de court-circuit
Par définition, les opérateurs booléens en court-circuit n'évalueront le deuxième opérande que si le premier opérande ne peut pas déterminer le résultat global de l'expression.
Cela signifie que si vous utilisez l'opérateur && comme firstCondition && secondCondition, il évaluera secondCondition uniquement lorsque firstCondition est true et ofcource le résultat global sera vrai seulement si firstOperand et secondOperand sont évalués à true. Ceci est utile dans de nombreux scénarios, par exemple imaginez que vous vouliez vérifier que votre liste comporte plus de trois éléments, mais vous devez également vérifier si la liste a été initialisée pour ne pas s'exécuter dans NullReferenceException . Vous pouvez y parvenir comme ci-dessous:
bool hasMoreThanThreeElements = myList != null && mList.Count > 3;
mList.Count> 3 ne sera pas coché jusqu'à ce que myList! = null soit rencontré.
Logique ET
&&
est la contrepartie de court-circuit de l'opérateur booléen AND ( &
) standard.
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).
OU logique
||
est la contrepartie de court-circuit de l'opérateur OR booléen standard ( |
).
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).
Exemple d'utilisation
if(object != null && object.Property)
// object.Property is never accessed if object is null, because of the short circuit.
Action1();
else
Action2();
taille de
Renvoie un int
contenant la taille d'un type * en octets.
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.
* Ne supporte que certains types primitifs dans un contexte sécurisé.
Dans un contexte non sécurisé, sizeof
peut être utilisé pour renvoyer la taille d'autres types et structures primitifs.
public struct CustomType
{
public int value;
}
static void Main()
{
unsafe
{
Console.WriteLine(sizeof(CustomType)); // outputs: 4
}
}
Surcharge des opérateurs d'égalité
La surcharge des opérateurs d'égalité ne suffit pas. Dans des circonstances différentes, tous les éléments suivants peuvent être appelés:
-
object.Equals
etobject.GetHashCode
-
IEquatable<T>.Equals
(facultatif, permet d'éviter la boxe) -
operator ==
etoperator !=
(optionnel, permet d'utiliser des opérateurs)
Lors de la substitution de Equals
, GetHashCode
doit également être remplacé. Lorsque vous implémentez Equals
, il existe de nombreux cas particuliers: comparer des objets d'un type différent, en les comparant à soi-même, etc.
Lorsque NOT surchargé, la méthode Equals
et l'opérateur ==
se comportent différemment pour les classes et les structures. Pour les classes, seules les références sont comparées, et pour les structures, les valeurs des propriétés sont comparées par réflexion, ce qui peut avoir un impact négatif sur les performances. ==
ne peut pas être utilisé pour comparer des structures à moins qu’elles ne soient surchargées.
En règle générale, l'opération d'égalité doit obéir aux règles suivantes:
- Ne pas jeter d'exceptions .
- Réflexivité:
A
toujours égal àA
(peut ne pas être vrai pour les valeursNULL
dans certains systèmes). - Transitvity: si
A
est égal àB
etB
est égal àC
, alorsA
est égal àC
- Si
A
est égal àB
, alorsA
etB
ont des codes de hachage égaux. - Indépendance de l'arbre d'héritage: si
B
etC
sont des instances deClass2
héritées deClass1
:Class1.Equals(A,B)
doivent toujours renvoyer la même valeur que l'appel à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);
}
}
Opérateurs membres de classe: Accès membres
var now = DateTime.UtcNow;
//accesses member of a class. In this case the UtcNow property.
Opérateurs membres de classe: accès conditionnel nul aux membres
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;
Opérateurs membres de classe: invocation de fonction
var age = GetAge(dateOfBirth);
//the above calls the function GetAge passing parameter dateOfBirth.
Opérateurs membres de classe: indexation d'objets agrégés
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].
Opérateurs membres de classe: indexation conditionnelle nulle
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
Opérateur "exclusif ou"
L'opérateur d'un "exclusif ou" (pour XOR court) est: ^
Cet opérateur renvoie true lorsqu'un, mais un seul, des bools fournis est vrai.
true ^ false // Returns true
false ^ true // Returns true
false ^ false // Returns false
true ^ true // Returns false
Opérateurs de transfert de bits
Les opérateurs de décalage permettent aux programmeurs d'ajuster un entier en déplaçant tous ses bits vers la gauche ou la droite. Le diagramme suivant montre l’effet du décalage d’une valeur vers la gauche par un chiffre.
Décalage à gauche
uint value = 15; // 00001111
uint doubled = value << 1; // Result = 00011110 = 30
uint shiftFour = value << 4; // Result = 11110000 = 240
Décalage de droite
uint value = 240; // 11110000
uint halved = value >> 1; // Result = 01111000 = 120
uint shiftFour = value >> 4; // Result = 00001111 = 15
Opérateurs de diffusion implicite et de distribution explicite
C # permet aux types définis par l'utilisateur de contrôler l'affectation et la diffusion via l'utilisation des mots clés explicit
et implicit
. La signature de la méthode prend la forme:
public static <implicit/explicit> operator <ResultingType>(<SourceType> myType)
La méthode ne peut pas prendre plus d'arguments, ni être une méthode d'instance. Il peut cependant accéder à tous les membres privés de type défini dans le document.
Un exemple à la fois d'une distribution implicit
et 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;
}
}
Permettant la syntaxe de distribution suivante:
var binaryImage = new BinaryImage();
ColorImage colorImage = binaryImage; // implicit cast, note the lack of type
bool[] pixels = (bool[])binaryImage; // explicit cast, defining the type
Les opérateurs de distribution peuvent travailler dans les deux sens, en allant de votre type à votre type:
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);
}
}
Enfin, le mot-clé as
, qui peut être utilisé pour la conversion au sein d'une hiérarchie de types, n'est pas valide dans cette situation. Même après avoir défini une distribution explicit
ou implicit
, vous ne pouvez pas faire:
ColorImage cm = myBinaryImage as ColorImage;
Cela générera une erreur de compilation.
Opérateurs binaires avec affectation
C # a plusieurs opérateurs qui peuvent être combinés avec un signe =
pour évaluer le résultat de l'opérateur, puis attribuer le résultat à la variable d'origine.
Exemple:
x += y
est le même que
x = x + y
Opérateurs d'affectation:
-
+=
-
-=
-
*=
-
/=
-
%=
-
&=
-
|=
-
^=
-
<<=
-
>>=
? : Opérateur ternaire
Renvoie l'une des deux valeurs en fonction de la valeur d'une expression booléenne.
Syntaxe:
condition ? expression_if_true : expression_if_false;
Exemple:
string name = "Frank";
Console.WriteLine(name == "Frank" ? "The name is Frank" : "The name is not Frank");
L'opérateur ternaire est associé à droite, ce qui permet d'utiliser des expressions ternaires composées. Ceci est fait en ajoutant des équations ternaires supplémentaires dans la position vraie ou fausse d'une équation ternaire parente. Des précautions doivent être prises pour assurer la lisibilité, mais cela peut être utile dans certaines circonstances.
Dans cet exemple, une opération ternaire composé évalue une clamp
fonction et retourne la valeur courante si elle est comprise dans l'intervalle, le min
valeur si elle est inférieure à la plage, ou le max
de valeur si elle est supérieure à la plage.
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;
}
Les opérateurs ternaires peuvent également être imbriqués, tels que:
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
Lors de l'écriture d'instructions ternaires composées, il est courant d'utiliser des parenthèses ou des indentations pour améliorer la lisibilité.
Les types de expression_if_true et expression_if_false doivent être identiques ou il doit y avoir une conversion implicite de l'un à l'autre.
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`.
Le type et les conditions de conversion s'appliquent également à vos propres classes.
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`.
Type de
Obtient l'objet System.Type
pour un type.
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]
Pour obtenir le type d'exécution, utilisez la méthode GetType
pour obtenir le System.Type
de l'instance actuelle.
Opérateur typeof
prend un nom de type en paramètre, spécifié lors de la compilation.
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
Opérateur par défaut
Type de valeur (où T: struct)
Les types de données primitifs intégrés, tels que char
, int
et float
, ainsi que les types définis par l'utilisateur déclarés avec struct
ou enum
. Leur valeur par défaut est 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
Type de référence (où T: classe)
Tout type de class
, interface
, tableau ou délégué. Leur valeur par défaut est null
:
default(object) // null
default(string) // null
default(MyClass) // null
default(IDisposable) // null
default(dynamic) // null
nom de l'opérateur
Renvoie une chaîne qui représente le nom non qualifié d'une variable
, d'un type
ou d'un member
.
int counter = 10;
nameof(counter); // Returns "counter"
Client client = new Client();
nameof(client.Address.PostalCode)); // Returns "PostalCode"
L'opérateur nameof
été introduit dans C # 6.0. Il est évalué à la compilation et la valeur de chaîne renvoyée est insérée en ligne par le compilateur. Il peut donc être utilisé dans la plupart des cas où la chaîne constante peut être utilisée (par exemple, les étiquettes de case
dans une instruction switch
, les attributs, etc. .). Cela peut être utile dans des cas comme lever et enregistrer des exceptions, des attributs, des liens d'action MVC, etc.
? (Opérateur conditionnel nul)
Introduit dans C # 6.0 , l'opérateur conditionnel nul ?.
renverra immédiatement null
si l'expression sur son côté gauche évalue à null
, au lieu de lancer une NullReferenceException
. Si son côté gauche donne une valeur non null
, il est traité comme une normale .
opérateur. Notez que, comme il peut renvoyer null
, son type de retour est toujours un type nullable. Cela signifie que pour un type struct ou primitif, il est enveloppé dans 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?
Cela est pratique lorsque vous tirez des événements. Normalement, vous devez placer l'appel d'événement dans une instruction if en vérifiant la valeur null
et déclencher l'événement par la suite, ce qui introduit la possibilité d'une situation de concurrence. En utilisant l’opérateur conditionnel Null, ceci peut être résolu de la manière suivante:
event EventHandler<string> RaiseMe;
RaiseMe?.Invoke("Event raised");
Incrémentation et décrémentation du postfixe et du préfixe
L'incrément de postfix X++
ajoutera 1
à x
var x = 42;
x++;
Console.WriteLine(x); // 43
Postfix décrément X--
soustraira un
var x = 42
x--;
Console.WriteLine(x); // 41
++x
est appelé incrément de préfixe, il incrémente la valeur de x et retourne x alors que x++
renvoie la valeur de x, puis s'incrémente
var x = 42;
Console.WriteLine(++x); // 43
System.out.println(x); // 43
tandis que
var x = 42;
Console.WriteLine(x++); // 42
System.out.println(x); // 43
les deux sont couramment utilisés dans la boucle
for(int i = 0; i < 10; i++)
{
}
=> Opérateur Lambda
L'opérateur =>
a la même priorité que l'opérateur d'affectation =
et est associé à droite.
Il est utilisé pour déclarer des expressions lambda et est également largement utilisé avec les requêtes LINQ :
string[] words = { "cherry", "apple", "blueberry" };
int shortestWordLength = words.Min((string w) => w.Length); //5
Lorsqu'il est utilisé dans des extensions LINQ ou des requêtes, le type des objets peut généralement être ignoré car il est déduit par le compilateur:
int shortestWordLength = words.Min(w => w.Length); //also compiles with the same result
La forme générale de l'opérateur lambda est la suivante:
(input parameters) => expression
Les paramètres de l'expression lambda sont spécifiés avant =>
opérateur, et l'expression / statement / block à exécuter est à droite de l'opérateur:
// 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);
}
Cet opérateur peut être utilisé pour définir facilement des délégués, sans écrire de méthode explicite:
delegate void TestDelegate(string s);
TestDelegate myDelegate = s => Console.WriteLine(s + " World");
myDelegate("Hello");
au lieu de
void MyMethod(string s)
{
Console.WriteLine(s + " World");
}
delegate void TestDelegate(string s);
TestDelegate myDelegate = MyMethod;
myDelegate("Hello");
Opérateur d'affectation '='
L'opérateur d'affectation =
définit la valeur de l'opérande de gauche à la valeur de l'opérande de droite et renvoie cette valeur:
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
?? Opérateur de coalescence nulle
L'opérateur Null-Coalescing ??
renverra le côté gauche lorsqu'il n'est pas nul. S'il est nul, il renverra le côté droit.
object foo = null;
object bar = new object();
var c = foo ?? bar;
//c will be bar since foo was null
Le ??
l'opérateur peut être enchaîné, ce qui permet de supprimer les contrôles if
.
//config will be the first non-null returned.
var config = RetrieveConfigOnMachine() ??
RetrieveConfigFromService() ??
new DefaultConfiguration();