Operatorüberladungen
Hinweis
Diese Inhalte wurden mit Genehmigung von Pearson Education, Inc. aus Framework Design Guidelines nachgedruckt: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition. Diese Ausgabe wurde 2008 veröffentlicht, und das Buch wurde seitdem in der dritten Ausgabe vollständig überarbeitet. Einige der Informationen auf dieser Seite sind möglicherweise veraltet.
Mit Operatorüberladungen können Frameworktypen so angezeigt werden, als wären sie integrierte Sprachgrundtypen.
Obwohl sie zulässig und in manchen Situationen nützlich sind, sollten Operatorüberladungen mit Vorsicht verwendet werden. In vielen Fällen wurden Operatorüberladungen missbräuchlich angewandt, z. B. wenn Frameworkdesigner begannen, Operatoren für Vorgänge zu verwenden, die einfache Methoden sein sollten. Die folgenden Richtlinien sollen Sie bei der Entscheidung unterstützen, wann und wie die Operatorüberladung verwendet werden soll.
❌ VERMEIDEN Sie das Definieren von Operatorüberladungen, außer in Typen, die sich wie Grundtypen (integrierte Typen) verhalten sollten.
✔️ ERWÄGEN Sie, Operatorüberladungen in einem Typ zu definieren, der sich wie ein Grundtyp verhalten sollte.
Beispiel: Für System.String sind operator==
und operator!=
definiert.
✔️ DEFINIEREN Sie Operatorüberladungen in Strukturen, die Zahlen darstellen (z. B. System.Decimal).
❌ Seien Sie beim Definieren von Operatorüberladungen NICHT NACHSICHTIG.
Die Operatorüberladung ist nützlich in Fällen, in denen sofort offensichtlich ist, was das Ergebnis des Vorgangs sein wird. Beispielsweise ist es sinnvoll, ein DateTime von einem anderen DateTime
zu subtrahieren und eine TimeSpan zu erhalten. Es ist jedoch nicht angemessen, den logischen Union-Operator zur Vereinigung zweier Datenbankabfragen oder den Shift-Operator zum Schreiben in einen Stream zu verwenden.
❌ Geben Sie KEINE Operatorüberladungen an, sofern nicht mindestens einer der Operanden von dem Typ ist, der die Überladung definiert.
✔️ ÜBERLADEN Sie Operatoren symmetrisch.
Wenn Sie z. B. operator==
überladen, sollten Sie auch operator!=
überladen. Ebenso sollten Sie auch operator>
überladen, wenn Sie operator<
überladen, usw.
✔️ ERWÄGEN Sie, Methoden mit Anzeigenamen bereitzustellen, die den einzelnen überladenen Operatoren entsprechen.
Viele Sprachen unterstützen die Operatorüberladung nicht. Aus diesem Grund wird empfohlen, dass Typen, die Operatoren überladen, eine sekundäre Methode mit einem entsprechenden domänenspezifischen Namen enthalten, die entsprechende Funktionalität bereitstellt.
Die folgende Tabelle enthält eine Liste der Operatoren und der entsprechenden Methodenanzeigenamen.
C#-Operatorsymbol | Metadatenname | Anzeigename |
---|---|---|
N/A |
op_Implicit |
To<TypeName>/From<TypeName> |
N/A |
op_Explicit |
To<TypeName>/From<TypeName> |
+ (binary) |
op_Addition |
Add |
- (binary) |
op_Subtraction |
Subtract |
* (binary) |
op_Multiply |
Multiply |
/ |
op_Division |
Divide |
% |
op_Modulus |
Mod or Remainder |
^ |
op_ExclusiveOr |
Xor |
& (binary) |
op_BitwiseAnd |
BitwiseAnd |
| |
op_BitwiseOr |
BitwiseOr |
&& |
op_LogicalAnd |
And |
|| |
op_LogicalOr |
Or |
= |
op_Assign |
Assign |
<< |
op_LeftShift |
LeftShift |
>> |
op_RightShift |
RightShift |
N/A |
op_SignedRightShift |
SignedRightShift |
N/A |
op_UnsignedRightShift |
UnsignedRightShift |
== |
op_Equality |
Equals |
!= |
op_Inequality |
Equals |
> |
op_GreaterThan |
CompareTo |
< |
op_LessThan |
CompareTo |
>= |
op_GreaterThanOrEqual |
CompareTo |
<= |
op_LessThanOrEqual |
CompareTo |
*= |
op_MultiplicationAssignment |
Multiply |
-= |
op_SubtractionAssignment |
Subtract |
^= |
op_ExclusiveOrAssignment |
Xor |
<<= |
op_LeftShiftAssignment |
LeftShift |
%= |
op_ModulusAssignment |
Mod |
+= |
op_AdditionAssignment |
Add |
&= |
op_BitwiseAndAssignment |
BitwiseAnd |
|= |
op_BitwiseOrAssignment |
BitwiseOr |
, |
op_Comma |
Comma |
/= |
op_DivisionAssignment |
Divide |
-- |
op_Decrement |
Decrement |
++ |
op_Increment |
Increment |
- (unary) |
op_UnaryNegation |
Negate |
+ (unary) |
op_UnaryPlus |
Plus |
~ |
op_OnesComplement |
OnesComplement |
Überladungsoperator ==
Das Überladen von operator ==
ist recht kompliziert. Die Semantik des Operators muss mit mehreren anderen Membern kompatibel sein, z. B. Object.Equals.
Konvertierungsoperatoren
Konvertierungsoperatoren sind unäre Operatoren, die eine Konvertierung von einem Typ in einen anderen ermöglichen. Die Operatoren müssen entweder für den Operanden oder den Rückgabetyp als statische Member definiert werden. Es gibt zwei Typen von Konvertierungsoperatoren: implizite und explizite.
❌ Geben Sie KEINEN Konvertierungsoperator an, wenn eine solche Konvertierung von den Endbenutzern nicht eindeutig erwartet wird.
❌ Definieren Sie KEINE Konvertierungsoperatoren außerhalb der Domäne eines Typs.
Beispielsweise sind Int32, Double und Decimal alle numerische Typen, DateTime hingegen nicht. Daher sollte es keinen Konvertierungsoperator geben, um Double(long)
in DateTime
zu konvertieren. In einem solchen Fall wird ein Konstruktor bevorzugt.
❌ Geben Sie KEINEN impliziten Konvertierungsoperator an, wenn die Konvertierung potenziell verlustbehaftet ist.
Beispielsweise sollte es keine implizite Konvertierung von Double
in Int32
geben, da Double
über einen größeren Bereich als Int32
verfügt. Ein expliziter Konvertierungsoperator kann auch dann bereitgestellt werden, wenn die Konvertierung potenziell verlustbehaftet ist.
❌Lösen Sie KEINE Ausnahmen aus impliziten Umwandlungen heraus aus.
Es ist für Endbenutzer sehr schwer zu verstehen, was passiert, da sie möglicherweise nicht erkennen, dass eine Konvertierung stattfindet.
✔️ Lösen Sie KEINE System.InvalidCastException aus, wenn ein Aufruf eines Umwandlungsoperators eine verlustbehaftete Konvertierung auslöst und der Vertrag des Operators keine verlustbehafteten Konvertierungen zulässt.
Teile ©2005, 2009 Microsoft Corporation. Alle Rechte vorbehalten.
Nachdruck mit Genehmigung von Pearson Education, Inc aus Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition von Krzysztof Cwalina und Brad Abrams, veröffentlicht am 22. Oktober 2008 durch Addison-Wesley Professional als Teil der Microsoft Windows Development Series.