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.

Weitere Informationen