C# Language
operators
Zoeken…
Invoering
In C # is een operator een programma-element dat wordt toegepast op een of meer operanden in een uitdrukking of instructie. Operatoren die één operand gebruiken, zoals de incrementoperator (++) of nieuw, worden unaire operatoren genoemd. Operatoren die twee operanden gebruiken, zoals rekenkundige operatoren (+, -, *, /), worden binaire operatoren genoemd. Eén operator, de voorwaardelijke operator (? :), neemt drie operanden en is de enige ternaire operator in C #.
Syntaxis
- public static OperandType operator operatorSymbool (OperandType operand1)
- public static OperandType operator operatorSymbool (OperandType operand1, OperandType2 operand2)
parameters
Parameter | Details |
---|---|
operatorSymbol | De operator wordt overbelast, bijv. +, -, /, * |
OperandType | Het type dat wordt geretourneerd door de overbelaste operator. |
operand1 | De eerste operand die moet worden gebruikt bij het uitvoeren van de bewerking. |
operand2 | De tweede operand die moet worden gebruikt bij het uitvoeren van de bewerking, bij het uitvoeren van binaire bewerkingen. |
statements | Optionele code nodig om de bewerking uit te voeren voordat het resultaat wordt geretourneerd. |
Opmerkingen
Alle operators zijn gedefinieerd als static methods
en ze zijn niet virtual
en ze zijn niet geërfd.
Voorrang operator
Alle operators hebben een bepaalde "prioriteit", afhankelijk van de groep waarin de operator valt (operators van dezelfde groep hebben dezelfde prioriteit). Dit betekent dat sommige operators eerder dan andere worden toegepast. Wat volgt is een lijst van groepen (met hun respectieve operatoren) geordend op prioriteit (hoogste eerst):
Primaire exploitanten
-
ab
- Toegang leden. -
a?.b
- Null voorwaardelijkea?.b
. -
->
- Verwijdering van aanwijzers gecombineerd met toegang voor leden. -
f(x)
- Functie-aanroeping. -
a[x]
- Indexeerder. -
a?[x]
- Null voorwaardelijke indexer. -
x++
- Postfix-toename. -
x--
- Postfix-verlaging. -
new
- typ instantiatie. -
default(T)
- Retourneert de standaard geïnitialiseerde waarde van typeT
-
typeof
- Retourneert hetType
object van de operand. -
checked
- Schakelt numerieke overloopcontrole in. -
unchecked
- Schakelt numerieke overloopcontrole uit. -
delegate
- Declareert en retourneert een gedelegeerde instantie. -
sizeof
- Retourneert de grootte in bytes van het type operand.
-
Unaire operatoren
-
+x
- Retourneertx
. -
-x
- Numerieke ontkenning. -
!x
- Logische ontkenning. -
~x
- Bitwise complement / verklaart destructors. -
++x
- Voorvoegsel verhogen. -
--x
- Voorvoegsel afname. -
(T)x
- Type casting. -
await
- wacht op eenTask
. -
&x
- Retourneert het adres (aanwijzer) vanx
. -
*x
- Verwijzing naar aanwijzer.
-
Multiplicatieve operators
-
x * y
- vermenigvuldiging. -
x / y
- Divisie. -
x % y
- Modulus.
-
Additieve operators
-
x + y
- toevoeging. -
x – y
- Aftrekken.
-
Bitwise Shift-operators
-
x << y
- Shift-bits over. -
x >> y
- Shift bits naar rechts.
-
Operators voor relationele / typetests
-
x < y
- Minder dan. -
x > y
- Groter dan. -
x <= y
- Kleiner dan of gelijk aan. -
x >= y
- Groter dan of gelijk aan. -
is
- Type compatibiliteit. -
as
- Type conversie.
-
Gelijkheidsexploitanten
-
x == y
- Gelijkheid. -
x != y
- Niet gelijk.
-
Logisch EN operator
-
x & y
- Logisch / bitsgewijs EN.
-
Logische XOR-operator
-
x ^ y
- Logisch / bitgewijs XOR.
-
Logisch OF operator
-
x | y
- Logisch / bitgewijs OF.
-
Voorwaardelijke EN operator
-
x && y
- Logische EN-kortsluiting.
-
Voorwaardelijke OF operator
-
x || y
- Logische kortsluiting OF.
-
Null-coalescerende operator
-
x ?? y
- Retourneertx
als deze niet nul is; anders wordty
geretourneerd.
-
Voorwaardelijke operator
-
x ? y : z
- Evalueert / retourneerty
alsx
waar is; anders wordtz
geëvalueerd.
-
gerelateerde inhoud
Overbelastbare operators
Met C # kunnen door de gebruiker gedefinieerde typen operators worden overbelast door statische lidfuncties te definiëren met behulp van het trefwoord operator
.
Het volgende voorbeeld illustreert een implementatie van de operator +
.
Als we een Complex
klasse hebben die een complex getal vertegenwoordigt:
public struct Complex
{
public double Real { get; set; }
public double Imaginary { get; set; }
}
En we willen de optie toevoegen om de operator +
voor deze klasse te gebruiken. d.w.z:
Complex a = new Complex() { Real = 1, Imaginary = 2 };
Complex b = new Complex() { Real = 4, Imaginary = 8 };
Complex c = a + b;
We moeten de operator +
voor de klas overbelasten. Dit wordt gedaan met behulp van een statische functie en het operator
:
public static Complex operator +(Complex c1, Complex c2)
{
return new Complex
{
Real = c1.Real + c2.Real,
Imaginary = c1.Imaginary + c2.Imaginary
};
}
Operators zoals +
, -
, *
, /
kunnen allemaal worden overbelast. Dit omvat ook operators die niet hetzelfde type retourneren (bijvoorbeeld ==
en !=
Kunnen overbelast raken, ondanks terugkerende booleans) De onderstaande regel met betrekking tot paren wordt hier ook toegepast.
Vergelijkingsoperatoren moeten in paren worden overbelast (bijv. Als <
is overbelast, >
ook worden overbelast).
Een volledige lijst van overbelastbare operators (evenals niet-overbelastbare operators en de beperkingen voor sommige overbelastbare operators) is te vinden op MSDN - Overloadable Operators (C # Programmeerhandleiding) .
overbelasting van de operator is
geïntroduceerd met het patroonvergelijkingsmechanisme van C # 7.0. Zie Patroonovereenkomst voor meer informatie
Gegeven een type Cartesian
als volgt gedefinieerd
public class Cartesian
{
public int X { get; }
public int Y { get; }
}
Een overbelast operator is
zou bijvoorbeeld kunnen worden gedefinieerd voor Polar
coördinaten
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;
}
}
die zo kan worden gebruikt
var c = Cartesian(3, 4);
if (c is Polar(var R, *))
{
Console.WriteLine(R);
}
(Het voorbeeld is afkomstig uit de Roslyn Pattern Matching Documentation )
Relationele operators
Equals
Controleert of de opgegeven operanden (argumenten) gelijk zijn
"a" == "b" // Returns false.
"a" == "a" // Returns true.
1 == 0 // Returns false.
1 == 1 // Returns true.
false == true // Returns false.
false == false // Returns true.
In tegenstelling tot Java werkt de vergelijkingsoperator voor gelijkheid native met tekenreeksen.
De operator voor het vergelijken van gelijkheden werkt met operanden van verschillende typen als er een impliciete cast van de ene naar de andere bestaat. Als er geen geschikte impliciete cast bestaat, kun je een expliciete cast oproepen of een methode gebruiken om naar een compatibel type te converteren.
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.
In tegenstelling tot Visual Basic.NET is de vergelijkingsoperator voor gelijkheid niet dezelfde als de operator voor gelijkheidstoewijzing.
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.
Niet te verwarren met de toewijzingsoperator ( =
).
Voor waardetypen retourneert de operator true
als beide operanden qua waarde gelijk zijn.
Voor referentietypen retourneert de operator true
als beide operanden gelijk zijn in referentie (geen waarde). Een uitzondering is dat stringobjecten worden vergeleken met waarde-gelijkheid.
Niet gelijk aan
Controleert of de geleverde operanden niet gelijk zijn.
"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.
Deze operator retourneert effectief het tegenovergestelde resultaat met dat van de operator is gelijk aan ( ==
)
Groter dan
Controleert of de eerste operand groter is dan de tweede operand.
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.
Minder dan
Controleert of de eerste operand kleiner is dan de tweede operand.
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.
Groter dan gelijk aan
Controleert of de eerste operand groter is dan gelijk aan de tweede operand.
7 >= 8 //Returns false.
0 >= 0 //Returns true.
Minder dan gelijk aan
Controleert of de eerste operand kleiner is dan gelijk aan de tweede operand.
2 <= 4 //Returns true.
1 <= -3 //Returns false.
1 <= 1 //Returns true.
Kortsluitende operators
De kortsluitende booleaanse operatoren zullen per definitie alleen de tweede operand evalueren als de eerste operand het totale resultaat van de uitdrukking niet kan bepalen.
Het betekent dat, als u de operator && gebruikt als firstCondition && secondCondition , secondCondition alleen wordt geëvalueerd als firstCondition waar is en het algemene resultaat alleen waar is als zowel firstOperand en secondOperand als waar worden geëvalueerd. Dit is handig in veel scenario's, stel u bijvoorbeeld voor dat u wilt controleren terwijl uw lijst meer dan drie elementen bevat, maar u moet ook controleren of de lijst is geïnitialiseerd om NullReferenceException niet te gebruiken. U kunt dit bereiken zoals hieronder:
bool hasMoreThanThreeElements = myList != null && mList.Count > 3;
mList.Count> 3 wordt niet gecontroleerd totdat myList! = null is bereikt.
Logisch EN
&&
is de kortgesloten tegenhanger van de standaard Booleaanse AND ( &
) -operator.
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).
Logisch OF
||
is de kortgesloten tegenhanger van de standaard booleaanse OR ( |
) -operator.
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).
Voorbeeld gebruik
if(object != null && object.Property)
// object.Property is never accessed if object is null, because of the short circuit.
Action1();
else
Action2();
De grootte van
Retourneert een int
met de grootte van een type * in 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.
* Ondersteunt alleen bepaalde primitieve typen in veilige context.
In een onveilige context kan sizeof
worden gebruikt om de grootte van andere primitieve typen en structuren te retourneren.
public struct CustomType
{
public int value;
}
static void Main()
{
unsafe
{
Console.WriteLine(sizeof(CustomType)); // outputs: 4
}
}
Overbelasting van gelijkheidsexploitanten
Overbelasting van alleen gelijkheidsexploitanten is niet voldoende. Onder verschillende omstandigheden kan het volgende worden aangeroepen:
-
object.Equals
enobject.GetHashCode
-
IEquatable<T>.Equals
(optioneel, voorkomt boksen) -
operator ==
enoperator !=
(optioneel, maakt gebruik van operators mogelijk)
Wanneer dwingende Equals
, GetHashCode
moet ook overschreven. Bij het implementeren van Equals
zijn er veel speciale gevallen: vergelijken met objecten van een ander type, vergelijken met zichzelf, enz.
Als hij niet overschreven Equals
methode en ==
operator gedragen zich anders voor de klassen en structuren. Voor klassen worden alleen referenties vergeleken, en voor structs worden waarden van eigenschappen vergeleken via reflectie wat de prestaties negatief kan beïnvloeden. ==
kan niet worden gebruikt voor het vergelijken van structs, tenzij het wordt overschreven.
Over het algemeen moet de gelijkheidsbewerking de volgende regels volgen:
- Mag geen uitzonderingen maken .
- Reflexiviteit:
A
altijd gelijk aanA
(is mogelijk niet waar voorNULL
waarden in sommige systemen). - Transitvity: als
A
gelijk is aanB
enB
gelijk is aanC
, dan isA
gelijk aanC
- Als
A
gelijk is aanB
, dan hebbenA
enB
gelijke hash-codes. - Overervingsboom onafhankelijkheid: als
B
enC
zijn voorbeelden vanClass2
geërfd vanClass1
:Class1.Equals(A,B)
altijd dezelfde waarde retourneren als aanroepClass2.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);
}
}
Class Member Operators: Toegang voor leden
var now = DateTime.UtcNow;
//accesses member of a class. In this case the UtcNow property.
Klasse-exploitanten: Null voorwaardelijke toegang voor leden
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;
Class Member Operators: Functie-aanroeping
var age = GetAge(dateOfBirth);
//the above calls the function GetAge passing parameter dateOfBirth.
Class Member-exploitanten: geaggregeerde objectindexering
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].
Klasse-exploitanten: Null voorwaardelijke indexering
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
"Exclusief of" Operator
De operator voor een "exclusief of" (kortweg XOR) is: ^
Deze operator retourneert true wanneer één, maar slechts één, van de geleverde bools waar is.
true ^ false // Returns true
false ^ true // Returns true
false ^ false // Returns false
true ^ true // Returns false
Bit-shift operators
Met de shift-operators kunnen programmeurs een geheel getal aanpassen door alle bits naar links of rechts te verschuiven. Het volgende diagram toont het effect van het met één cijfer naar links schuiven van een waarde.
Linker shift
uint value = 15; // 00001111
uint doubled = value << 1; // Result = 00011110 = 30
uint shiftFour = value << 4; // Result = 11110000 = 240
Rechts-Shift
uint value = 240; // 11110000
uint halved = value >> 1; // Result = 01111000 = 120
uint shiftFour = value >> 4; // Result = 00001111 = 15
Impliciete cast- en expliciete cast-operators
Met C # kunnen door de gebruiker gedefinieerde typen de toewijzing en het casten beheren door het gebruik van de explicit
en implicit
zoekwoorden. De handtekening van de methode heeft de vorm:
public static <implicit/explicit> operator <ResultingType>(<SourceType> myType)
De methode kan geen argumenten meer aannemen, noch kan het een instantiemethode zijn. Het heeft echter toegang tot alle privéleden van het type waarin het is gedefinieerd.
Een voorbeeld van zowel een implicit
als een explicit
cast:
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;
}
}
De volgende syntaxis van cast toestaan:
var binaryImage = new BinaryImage();
ColorImage colorImage = binaryImage; // implicit cast, note the lack of type
bool[] pixels = (bool[])binaryImage; // explicit cast, defining the type
De cast-operators kunnen op beide manieren werken, gaande van uw type en naar uw 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);
}
}
Ten slotte is het sleutelwoord as
, dat kan worden betrokken bij het casten binnen een typehiërarchie, niet geldig in deze situatie. Zelfs na het definiëren van een explicit
of implicit
cast, kunt u niet doen:
ColorImage cm = myBinaryImage as ColorImage;
Het zal een compilatiefout genereren.
Binaire operatoren met opdracht
C # heeft verschillende operators die kunnen worden gecombineerd met een =
-teken om het resultaat van de operator te evalueren en vervolgens het resultaat toe te wijzen aan de oorspronkelijke variabele.
Voorbeeld:
x += y
is hetzelfde als
x = x + y
Opdrachtexploitanten:
-
+=
-
-=
-
*=
-
/=
-
%=
-
&=
-
|=
-
^=
-
<<=
-
>>=
? : Ternary Operator
Retourneert een van twee waarden, afhankelijk van de waarde van een Booleaanse uitdrukking.
Syntaxis:
condition ? expression_if_true : expression_if_false;
Voorbeeld:
string name = "Frank";
Console.WriteLine(name == "Frank" ? "The name is Frank" : "The name is not Frank");
De ternaire operator is recht-associatief waardoor samengestelde ternaire expressies kunnen worden gebruikt. Dit wordt gedaan door extra ternaire vergelijkingen toe te voegen in de ware of valse positie van een bovenliggende ternaire vergelijking. Zorg ervoor dat de leesbaarheid wordt gewaarborgd, maar dit kan in sommige omstandigheden handig zijn.
In dit voorbeeld evalueert een samengestelde ternaire bewerking een clamp
en retourneert de huidige waarde als deze binnen het bereik ligt, de min
als deze onder het bereik ligt of de max
waarde als deze boven het bereik ligt.
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;
}
Ternary-operatoren kunnen ook worden genest, zoals:
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
Bij het schrijven van samengestelde ternaire uitspraken is het gebruikelijk om haakjes of inspringen te gebruiken om de leesbaarheid te verbeteren.
De typen expression_if_true en expression_if_false moeten identiek zijn of er moet een impliciete conversie van de ene naar de andere zijn.
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`.
De vereisten voor type en conversie zijn ook van toepassing op uw eigen klassen.
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`.
soort van
Krijgt System.Type
object voor een 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]
Gebruik de GetType
methode om het runtime-type te verkrijgen om het System.Type
van het huidige exemplaar te verkrijgen.
Operator typeof
neemt een typenaam als parameter, die tijdens het compileren wordt opgegeven.
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
standaard operator
Waardetype (waarbij T: struct)
De ingebouwde primitieve gegevenstypen, zoals char
, int
en float
, evenals door de gebruiker gedefinieerde typen die zijn gedeclareerd met struct
of enum
. Hun standaardwaarde is 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
Referentietype (waar T: klasse)
Elk type class
, interface
, array of gedelegeerde. De standaardwaarde is null
:
default(object) // null
default(string) // null
default(MyClass) // null
default(IDisposable) // null
default(dynamic) // null
naam van de operator
Retourneert een tekenreeks die de niet-gekwalificeerde naam van een variable
, type
of member
.
int counter = 10;
nameof(counter); // Returns "counter"
Client client = new Client();
nameof(client.Address.PostalCode)); // Returns "PostalCode"
De operator nameof
werd geïntroduceerd in C # 6.0. Het wordt geëvalueerd tijdens het compileren en de geretourneerde tekenreeks waarde wordt inline ingevoegd bij de compiler, zodat het kan worden gebruikt in de meeste gevallen waarin de constante string kan worden gebruikt (bijvoorbeeld het case
in een labels switch
statement, attributen, enz .. .). Het kan nuttig zijn in gevallen zoals het verhogen en vastleggen van uitzonderingen, attributen, MVC Action links, enz ...
?. (Null voorwaardelijke operator)
Geïntroduceerd in C # 6.0 , de Null Conditional Operator ?.
zal onmiddellijk null
retourneren als de uitdrukking aan de linkerkant null
, in plaats van een NullReferenceException
gooien. Als de linkerkant naar een niet- null
evalueert, wordt deze als een normale behandeld .
operator. Merk op dat, omdat het mogelijk null
retourneert, het retourneringstype altijd een nulletterbaar type is. Dat betekent dat het voor een struct of primitief type is verpakt in een 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?
Dit komt van pas bij het afvuren van evenementen. Normaal gesproken zou je de event-call in een if-statement moeten plaatsen om op null
controleren en daarna het evenement moeten verhogen, wat de mogelijkheid van een race-conditie introduceert. Met de voorwaardelijke operator Null kan dit op de volgende manier worden opgelost:
event EventHandler<string> RaiseMe;
RaiseMe?.Invoke("Event raised");
Verhogen en verlagen van Postfix en Prefix
Postfix-toename X++
voegt 1
aan x
var x = 42;
x++;
Console.WriteLine(x); // 43
Postfix-verlaging X--
zal er één aftrekken
var x = 42
x--;
Console.WriteLine(x); // 41
++x
wordt voorvoegsel increment genoemd, het verhoogt de waarde van x en retourneert vervolgens x, terwijl x++
de waarde van x retourneert en vervolgens verhoogt
var x = 42;
Console.WriteLine(++x); // 43
System.out.println(x); // 43
terwijl
var x = 42;
Console.WriteLine(x++); // 42
System.out.println(x); // 43
beide worden vaak gebruikt in voor lus
for(int i = 0; i < 10; i++)
{
}
=> Lambda-operator
De operator =>
heeft dezelfde prioriteit als de operator operator =
en is rechts-associatief.
Het wordt gebruikt om lambda-expressies aan te geven en het wordt ook veel gebruikt met LINQ-zoekopdrachten :
string[] words = { "cherry", "apple", "blueberry" };
int shortestWordLength = words.Min((string w) => w.Length); //5
Bij gebruik in LINQ-extensies of -query's kan het type objecten meestal worden overgeslagen omdat het wordt afgeleid door de compiler:
int shortestWordLength = words.Min(w => w.Length); //also compiles with the same result
De algemene vorm van lambda-operator is de volgende:
(input parameters) => expression
De parameters van de lambda-expressie zijn opgegeven voor de operator =>
en de uit te voeren expressie / instructie / blok bevindt zich rechts van de operator:
// 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);
}
Deze operator kan worden gebruikt om eenvoudig afgevaardigden te definiëren, zonder een expliciete methode te schrijven:
delegate void TestDelegate(string s);
TestDelegate myDelegate = s => Console.WriteLine(s + " World");
myDelegate("Hello");
in plaats van
void MyMethod(string s)
{
Console.WriteLine(s + " World");
}
delegate void TestDelegate(string s);
TestDelegate myDelegate = MyMethod;
myDelegate("Hello");
Toewijzingsoperator '='
De toewijzingsoperator =
stelt de waarde van de linkerhandoperand in op de waarde van de rechterhandoperand en retourneert die waarde:
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
?? Null-coalescerende operator
De operator Null-Coalescing ??
retourneert de linkerkant als deze niet nul is. Als deze nul is, wordt de rechterkant geretourneerd.
object foo = null;
object bar = new object();
var c = foo ?? bar;
//c will be bar since foo was null
De ??
operator kan worden geketend waardoor if
cheques kunnen worden verwijderd.
//config will be the first non-null returned.
var config = RetrieveConfigOnMachine() ??
RetrieveConfigFromService() ??
new DefaultConfiguration();