C# Language
Operatoren
Suche…
Einführung
In C # ist ein Operator ein Programmelement, das auf einen oder mehrere Operanden in einem Ausdruck oder einer Anweisung angewendet wird. Operatoren, die einen Operanden verwenden, beispielsweise den Inkrementoperator (++) oder new, werden als unäre Operatoren bezeichnet. Operatoren, die zwei Operanden verwenden, wie beispielsweise arithmetische Operatoren (+, -, *, /), werden als binäre Operatoren bezeichnet. Ein Operator, der Bedingungsoperator (? :), nimmt drei Operanden auf und ist der einzige ternäre Operator in C #.
Syntax
- public static OperandType operator operatorSymbol (OperandType operand1)
- public static OperandType operator operatorSymbol (OperandType operand1, OperandType2 operand2)
Parameter
Parameter | Einzelheiten |
---|---|
operatorSymbol | Überladener Operator, zB +, -, /, * |
OperandType | Der Typ, der vom überladenen Operator zurückgegeben wird. |
operand1 | Der erste Operand, der zur Ausführung der Operation verwendet wird. |
operand2 | Der zweite Operand, der beim Ausführen der Operation verwendet wird, wenn binäre Operationen ausgeführt werden. |
Aussagen | Optionaler Code, der erforderlich ist, um die Operation auszuführen, bevor das Ergebnis zurückgegeben wird. |
Bemerkungen
Alle Operatoren sind als static methods
definiert, sie sind nicht virtual
und werden nicht vererbt.
Vorrang des Bedieners
Alle Operatoren haben eine bestimmte "Priorität", abhängig davon, in welche Gruppe der Operator fällt (Operatoren derselben Gruppe haben gleiche Priorität). Das heißt, einige Operatoren werden vor anderen angewendet. Was folgt, ist eine Liste von Gruppen (mit ihren jeweiligen Operatoren), sortiert nach Rang (höchste zuerst):
Primäroperatoren
-
ab
- Mitgliederzugang -
a?.b
-a?.b
bedingtera?.b
. -
->
- Zeiger-Dereferenzierung in Kombination mit Memberzugriff. -
f(x)
- Funktionsaufruf. -
a[x]
- Indexer. -
a?[x]
- Nullbedingter Indexer. -
x++
- Postfix-Inkrement. -
x--
- Postfix-Dekrement. -
new
- Typinstanziierung. -
default(T)
- Gibt den voreingestellten Standardwert des TypsT
. -
typeof
- Gibt dasType
Objekt des Operanden zurück. -
checked
- Aktiviert die Überprüfung des numerischen Überlaufs. -
unchecked
markiert - Deaktiviert die Überprüfung des numerischen Überlaufs. -
delegate
- Deklariert und gibt eine Delegat-Instanz zurück. -
sizeof
- Gibt die Größe des Operanden vom Typ in Bytes zurück.
-
Unäre Operatoren
-
+x
- Gibtx
. -
-x
- Numerische Negation. -
!x
- Logische Negation. -
~x
- Bitweise komplementieren / deklarieren Destruktoren. -
++x
- Präfixinkrement. -
--x
---x
. -
(T)x
- Gussteil. -
await
- Wartet auf eineTask
. -
&x
- Liefert die Adresse (Zeiger) vonx
. -
*x
- Zeiger-Dereferenzierung.
-
Multiplikative Operatoren
-
x * y
- Multiplikation. -
x / y
- Division. -
x % y
- Modul.
-
Additive Operatoren
-
x + y
- Addition. -
x – y
- Subtraktion.
-
Bitweise Verschiebungsoperatoren
-
x << y
- Bits nach links verschieben. -
x >> y
- Bits nach rechts verschieben.
-
Relational / Typprüfoperatoren
-
x < y
- Weniger als. -
x > y
- Größer als. -
x <= y
- kleiner oder gleich. -
x >= y
- Größer als oder gleich. -
is
- Typkompatibilität. -
as
- Typumwandlung.
-
Gleichheitsoperatoren
-
x == y
- Gleichheit. -
x != y
- Nicht gleich.
-
Logischer AND-Operator
-
x & y
- logisch / bitweise UND.
-
Logischer XOR-Operator
-
x ^ y
- Logisch / bitweise XOR.
-
Logischer ODER-Operator
-
x | y
- logisch / bitweise ODER.
-
Bedingter UND Operator
-
x && y
- Kurzschließen des logischen UND.
-
Bedingter ODER-Operator
-
x || y
- Kurzschließen eines logischen ODER.
-
Nullkoaleszenzoperator
-
x ?? y
- Gibtx
wenn es nicht null ist. ansonsten wirdy
.
-
Bedingter Operator
-
x ? y : z
- Wertety
wennx
wahr ist; ansonsten wirdz
.
-
Verwandte Inhalte
Überladbare Operatoren
In C # können benutzerdefinierte Typen Operatoren überladen, indem statische Memberfunktionen mithilfe des operator
Schlüsselworts definiert werden.
Das folgende Beispiel veranschaulicht eine Implementierung des Operators +
.
Wenn wir eine Complex
Klasse haben, die eine komplexe Zahl darstellt:
public struct Complex
{
public double Real { get; set; }
public double Imaginary { get; set; }
}
Und wir möchten die Option hinzufügen, um den Operator +
für diese Klasse zu verwenden. dh:
Complex a = new Complex() { Real = 1, Imaginary = 2 };
Complex b = new Complex() { Real = 4, Imaginary = 8 };
Complex c = a + b;
Wir müssen den Operator +
für die Klasse überladen. Dies geschieht mit einer statischen Funktion und dem operator
Schlüsselwort:
public static Complex operator +(Complex c1, Complex c2)
{
return new Complex
{
Real = c1.Real + c2.Real,
Imaginary = c1.Imaginary + c2.Imaginary
};
}
Operatoren wie +
, -
, *
, /
können alle überladen werden. Dies schließt auch Operatoren ein, die nicht denselben Typ zurückgeben (zum Beispiel ==
und !=
Können trotz der Rückgabe von Booleans überladen werden). Die folgende Regel, die sich auf Paare bezieht, wird hier ebenfalls durchgesetzt.
Vergleichsoperatoren müssen paarweise überladen werden (zB wenn <
überlastet ist, >
muss auch überlastet werden).
Eine vollständige Liste überladbarer Operatoren (sowie nicht überladbarer Operatoren und der Einschränkungen bei einigen überladbaren Operatoren) finden Sie unter MSDN - Überladbare Operatoren (C # -Programmierhandbuch) .
Überladen des operator is
wurde mit dem Pattern-Matching-Mechanismus von C # 7.0 eingeführt. Einzelheiten finden Sie unter Pattern Matching
Ein Typ Cartesian
ist wie folgt definiert
public class Cartesian
{
public int X { get; }
public int Y { get; }
}
Ein überladbarer operator is
kann zB für Polar
definiert werden
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;
}
}
das kann so verwendet werden
var c = Cartesian(3, 4);
if (c is Polar(var R, *))
{
Console.WriteLine(R);
}
(Das Beispiel stammt aus der Roslyn Pattern Matching-Dokumentation. )
Beziehungsoperatoren
Gleich
Prüft, ob die angegebenen Operanden (Argumente) gleich sind
"a" == "b" // Returns false.
"a" == "a" // Returns true.
1 == 0 // Returns false.
1 == 1 // Returns true.
false == true // Returns false.
false == false // Returns true.
Im Gegensatz zu Java arbeitet der Gleichheitsvergleichsoperator nativ mit Zeichenfolgen.
Der Gleichheitsvergleichsoperator arbeitet mit Operanden unterschiedlichen Typs, wenn eine implizite Umwandlung von einer zur anderen besteht. Wenn keine geeignete implizite Umwandlung vorhanden ist, können Sie eine explizite Umwandlung aufrufen oder eine Methode zum Konvertieren in einen kompatiblen Typ verwenden.
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.
Im Gegensatz zu Visual Basic.NET stimmt der Gleichheitsvergleichsoperator nicht mit dem Gleichheitszuweisungsoperator überein.
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.
Nicht zu verwechseln mit dem Zuweisungsoperator ( =
).
Bei Werttypen gibt der Operator den Wert true
zurück true
wenn beide Operanden den gleichen Wert haben.
Bei Referenztypen gibt der Operator " true
zurück true
wenn beide Operanden in der Referenz (nicht im Wert) gleich sind. Eine Ausnahme ist, dass String-Objekte mit der Wertegleichheit verglichen werden.
Nicht gleich
Prüft, ob die angegebenen Operanden nicht gleich sind.
"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.
Dieser Operator gibt effektiv das Gegenteil von dem Gleichheitsoperator ( ==
) zurück
Größer als
Prüft, ob der erste Operand größer als der zweite Operand ist.
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.
Weniger als
Prüft, ob der erste Operand kleiner als der zweite Operand ist.
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.
Größer als gleich
Prüft, ob der erste Operand größer als der zweite Operand ist.
7 >= 8 //Returns false.
0 >= 0 //Returns true.
Weniger als gleich
Prüft, ob der erste Operand kleiner als der zweite Operand ist.
2 <= 4 //Returns true.
1 <= -3 //Returns false.
1 <= 1 //Returns true.
Kurzschließen der Operatoren
Per Definition werden die booleschen Operatoren für den Kurzschluss nur dann ausgewertet, wenn der erste Operand das Gesamtergebnis des Ausdrucks nicht bestimmen kann.
Es bedeutet , dass, wenn Sie Operator && als firstCondition verwenden && secondCondition es secondCondition nur zu bewerten, wenn firstCondition wahr ist und ofcource das Gesamtergebnis nur dann , wenn beide firstOperand und secondOperand ausgewertet , um wahr wahr sein. Dies ist in vielen Szenarien hilfreich. Stellen Sie sich zum Beispiel vor, Sie möchten prüfen, obgleich Ihre Liste mehr als drei Elemente enthält. Sie müssen jedoch auch prüfen, ob die Liste initialisiert wurde, damit sie nicht in NullReferenceException ausgeführt wird . Sie können dies wie folgt erreichen:
bool hasMoreThanThreeElements = myList != null && mList.Count > 3;
mList.Count> 3 wird nicht geprüft, bis myList! = null erfüllt ist.
Logisches UND
&&
ist das kurzschließende Gegenstück zum Standard-Booleschen 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).
Logisches ODER
||
ist das kurzschließende Gegenstück des standardmäßigen booleschen OR ( |
) - Operators.
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).
Verwendungsbeispiel
if(object != null && object.Property)
// object.Property is never accessed if object is null, because of the short circuit.
Action1();
else
Action2();
Größe von
Gibt ein int
, das die Größe eines Typs * in Byte enthält.
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.
* Unterstützt nur bestimmte primitive Typen im sicheren Kontext.
In einem unsicheren Kontext kann sizeof
verwendet werden, um die Größe anderer primitiver Typen und Strukturen zurückzugeben.
public struct CustomType
{
public int value;
}
static void Main()
{
unsafe
{
Console.WriteLine(sizeof(CustomType)); // outputs: 4
}
}
Überladen von Gleichheitsoperatoren
Es reicht nicht aus, nur Gleichheitsoperatoren zu überladen. Unter verschiedenen Umständen kann Folgendes aufgerufen werden:
-
object.Equals
undobject.GetHashCode
-
IEquatable<T>.Equals
(optional, um Boxen zu vermeiden) -
operator ==
undoperator !=
(optional, ermöglicht die Verwendung von Operatoren)
Wenn Sie Equals
überschreiben, muss auch GetHashCode
überschrieben werden. Bei der Implementierung von Equals
gibt es viele Sonderfälle: Vergleiche mit Objekten eines anderen Typs, Vergleich mit sich selbst usw.
Wenn die Equals
Methode und der Operator ==
NICHT überschrieben werden, verhalten sie sich für Klassen und Strukturen unterschiedlich. Für Klassen werden nur Verweise verglichen, und für Strukturen werden Eigenschaftswerte durch Reflektion verglichen, was sich negativ auf die Leistung auswirken kann. ==
kann nicht für den Vergleich von Strukturen verwendet werden, es sei denn, es wird überschrieben.
Im Allgemeinen müssen bei der Gleichstellungsoperation die folgenden Regeln beachtet werden:
- Darf keine Ausnahmen werfen .
- Reflexivität:
A
immer gleichA
(in manchen Systemen fürNULL
Werte möglicherweise nicht zutreffend). - Transitvity: Wenn
A
gleichB
ist undB
gleichC
, dann istA
gleichC
- Wenn
A
gleichB
, habenA
undB
gleiche Hash-Codes. - Vererbungsbaum Unabhängigkeit: Wenn
B
undC
Fälle sindClass2
geerbt vonClass1
:Class1.Equals(A,B)
müssen den gleichen Wert wie der Aufruf immer wieder zurückkehrenClass2.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);
}
}
Klassenmitgliedsoperatoren: Mitgliederzugang
var now = DateTime.UtcNow;
//accesses member of a class. In this case the UtcNow property.
Klassenmitgliedsoperatoren: Kein Zugriff auf bedingte Mitglieder
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;
Klassenmitgliedsoperatoren: Funktionsaufruf
var age = GetAge(dateOfBirth);
//the above calls the function GetAge passing parameter dateOfBirth.
Klassenelementoperatoren: Aggregierte Objektindizierung
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].
Klassenmitgliedsoperatoren: Keine bedingte Indexierung
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
"Exklusiv" oder "Operator"
Der Operator für ein "exklusives oder" (kurz XOR) lautet: ^
Dieser Operator gibt true zurück, wenn einer, aber nur einer der gelieferten Booler wahr ist.
true ^ false // Returns true
false ^ true // Returns true
false ^ false // Returns false
true ^ true // Returns false
Bitverschiebungsoperatoren
Mit den Shift-Operatoren können Programmierer eine ganze Zahl anpassen, indem sie alle Bits nach links oder rechts verschieben. Das folgende Diagramm zeigt den Einfluss der Verschiebung eines Wertes um eine Ziffer nach links.
Linksverschiebung
uint value = 15; // 00001111
uint doubled = value << 1; // Result = 00011110 = 30
uint shiftFour = value << 4; // Result = 11110000 = 240
Rechte Shifttaste
uint value = 240; // 11110000
uint halved = value >> 1; // Result = 01111000 = 120
uint shiftFour = value >> 4; // Result = 00001111 = 15
Implizite Besetzung und explizite Besetzung Operatoren
Mit C # können benutzerdefinierte Typen die Zuweisung und das Casting mithilfe der explicit
und implicit
Schlüsselwörter steuern. Die Signatur der Methode hat die Form:
public static <implicit/explicit> operator <ResultingType>(<SourceType> myType)
Die Methode kann keine weiteren Argumente aufnehmen und kann auch keine Instanzmethode sein. Es kann jedoch auf private Mitglieder des Typs zugreifen, in dem es definiert ist.
Ein Beispiel für eine implicit
und explicit
Besetzung:
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;
}
}
Erlaube die folgende Cast-Syntax:
var binaryImage = new BinaryImage();
ColorImage colorImage = binaryImage; // implicit cast, note the lack of type
bool[] pixels = (bool[])binaryImage; // explicit cast, defining the type
Die Besetzungsoperatoren können auf beide Arten arbeiten, von Ihrem Typ zu Ihrem Typ:
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);
}
}
Schließlich ist das as
Schlüsselwort, das in einer Typhierarchie an der Umwandlung beteiligt sein kann, in dieser Situation nicht gültig. Selbst nachdem Sie eine explicit
oder implicit
Umwandlung definiert haben, können Sie Folgendes nicht tun:
ColorImage cm = myBinaryImage as ColorImage;
Es wird ein Kompilierungsfehler generiert.
Binäre Operatoren mit Zuordnung
C # verfügt über mehrere Operatoren, die mit einem =
-Zeichen kombiniert werden können, um das Ergebnis des Operators auszuwerten und das Ergebnis der ursprünglichen Variablen zuzuweisen.
Beispiel:
x += y
ist das gleiche wie
x = x + y
Zuweisungsoperatoren:
-
+=
-
-=
-
*=
-
/=
-
%=
-
&=
-
|=
-
^=
-
<<=
-
>>=
? : Ternärer Betreiber
Gibt einen von zwei Werten zurück, abhängig vom Wert eines booleschen Ausdrucks.
Syntax:
condition ? expression_if_true : expression_if_false;
Beispiel:
string name = "Frank";
Console.WriteLine(name == "Frank" ? "The name is Frank" : "The name is not Frank");
Der ternäre Operator ist rechtsassoziativ, so dass zusammengesetzte ternäre Ausdrücke verwendet werden können. Dies erfolgt durch Hinzufügen zusätzlicher ternärer Gleichungen an der wahren oder falschen Position einer ternären Elterngleichung. Es sollte darauf geachtet werden, dass die Lesbarkeit gewährleistet ist, dies kann jedoch unter Umständen kurz sein.
In diesem Beispiel wertet ein ternärer Verbindung Betrieb eine clamp
und gibt den aktuellen Wert , wenn er innerhalb des Bereichs ist, der min
- Wert , wenn es unterhalb dem Bereich ist, oder der max
- Wert , wenn es über dem Bereich ist.
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;
}
Ternäre Operatoren können auch verschachtelt werden, z.
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
Beim Schreiben von zusammengesetzten ternären Anweisungen werden zur Verbesserung der Lesbarkeit üblicherweise Klammern oder Einrückungen verwendet.
Die Typen expression_if_true und expression_if_false müssen identisch sein, oder es muss eine implizite Konvertierung von einer zur anderen vorliegen.
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`.
Die Typ- und Konvertierungsanforderungen gelten auch für Ihre eigenen 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`.
Art der
Ruft ein System.Type
Objekt für einen Typ ab.
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]
Verwenden Sie die GetType
Methode, um den System.Type
der aktuellen Instanz System.Type
.
Der Operator typeof
nimmt einen typeof
als Parameter an, der zur Kompilierzeit angegeben wird.
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
Standardoperator
Werttyp (wobei T: struct)
Die integrierten primitiven Datentypen wie char
, int
und float
sowie benutzerdefinierte Typen, die mit struct
oder enum
deklariert wurden Ihr Standardwert ist 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
Referenztyp (wobei T: Klasse)
Alle class
, interface
, Arrays oder Delegattypen. Der Standardwert ist null
:
default(object) // null
default(string) // null
default(MyClass) // null
default(IDisposable) // null
default(dynamic) // null
Name des Betreibers
Gibt eine Zeichenfolge zurück, die den nicht qualifizierten Namen einer variable
, eines type
oder eines member
.
int counter = 10;
nameof(counter); // Returns "counter"
Client client = new Client();
nameof(client.Address.PostalCode)); // Returns "PostalCode"
Der nameof
Operator wurde in C # 6.0 eingeführt. Es wird zur Compile-Zeit und der zurückgegebene String - Wert wird inline durch die Compiler eingefügt ausgewertet, so kann es in den meisten Fällen verwendet werden , wo der konstante String verwendet werden kann ( zum Beispiel der case
Etikett in einer switch
Anweisung, Attribute, etc .. .). Dies kann nützlich sein, wenn Ausnahmen, Attribute, MVC-Aktionslinks usw. ausgelöst und protokolliert werden.
. (Nullbedingter Operator)
In C # 6.0 wurde der nullbedingte Operator eingeführt ?.
gibt sofort null
wenn der Ausdruck auf der linken Seite als null
ausgewertet wird, anstatt eine NullReferenceException
. Wenn seine linke Seite einen Wert ungleich null
auswertet, wird er wie ein Normalwert behandelt .
Operator. Beachten Sie, dass der Rückgabetyp immer einen nullfähigen Typ ist, da er möglicherweise null
kann. Das bedeutet, dass es für einen Struktur- oder Primitivtyp in ein 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?
Dies ist praktisch, wenn Sie Ereignisse abfeuern. Normalerweise müssten Sie den Ereignisaufruf in eine if -Anweisung einschließen, die nach null
und das Ereignis anschließend auslösen, wodurch die Möglichkeit einer Race-Bedingung entsteht. Mit dem Null-Bedingungsoperator kann dies auf folgende Weise behoben werden:
event EventHandler<string> RaiseMe;
RaiseMe?.Invoke("Event raised");
Erhöhung und Abnahme von Postfix und Prefix
Postfix-Inkrement X++
fügt 1
zu x
var x = 42;
x++;
Console.WriteLine(x); // 43
Postfix-Dekrement X--
subtrahiert eins
var x = 42
x--;
Console.WriteLine(x); // 41
++x
wird als Präfix inkrement bezeichnet. Es erhöht den Wert von x und gibt dann x zurück, während x++
den Wert von x zurückgibt und dann erhöht
var x = 42;
Console.WriteLine(++x); // 43
System.out.println(x); // 43
während
var x = 42;
Console.WriteLine(x++); // 42
System.out.println(x); // 43
beide werden häufig in for-Schleife verwendet
for(int i = 0; i < 10; i++)
{
}
=> Lambda-Operator
Der Operator =>
hat dieselbe Priorität wie der Zuweisungsoperator =
und ist rechtsassoziativ.
Es wird verwendet, um Lambda-Ausdrücke zu deklarieren, und es wird auch häufig bei LINQ-Abfragen verwendet :
string[] words = { "cherry", "apple", "blueberry" };
int shortestWordLength = words.Min((string w) => w.Length); //5
Bei Verwendung in LINQ-Erweiterungen oder -Abfragen kann der Typ der Objekte normalerweise übersprungen werden, da er vom Compiler abgeleitet wird:
int shortestWordLength = words.Min(w => w.Length); //also compiles with the same result
Die allgemeine Form des Lambda-Operators ist die folgende:
(input parameters) => expression
Die Parameter des Lambda-Ausdrucks werden vor dem Operator =>
angegeben, und der tatsächlich auszuführende Ausdruck / Anweisung / Block befindet sich rechts vom 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);
}
Dieser Operator kann verwendet werden, um Delegaten einfach zu definieren, ohne eine explizite Methode zu schreiben:
delegate void TestDelegate(string s);
TestDelegate myDelegate = s => Console.WriteLine(s + " World");
myDelegate("Hello");
anstatt
void MyMethod(string s)
{
Console.WriteLine(s + " World");
}
delegate void TestDelegate(string s);
TestDelegate myDelegate = MyMethod;
myDelegate("Hello");
Zuweisungsoperator '='
Der Zuweisungsoperator =
setzt den Wert des linken Operanden auf den Wert des rechten Operanden und gibt diesen Wert zurück:
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
?? Nullkoaleszenzoperator
Der Null-Koaleszenz-Operator ??
wird die linke Seite zurückgeben, wenn nicht null. Wenn es null ist, wird die rechte Seite zurückgegeben.
object foo = null;
object bar = new object();
var c = foo ?? bar;
//c will be bar since foo was null
Die ??
Bediener können verkettet werden , welche die Entfernung von ermöglicht , if
überprüft.
//config will be the first non-null returned.
var config = RetrieveConfigOnMachine() ??
RetrieveConfigFromService() ??
new DefaultConfiguration();