2009-08-31 6 views
29

Ich habe einen Aufzählungstyp, den ich die>, <,> = und < = Operatoren für definieren möchte. Ich weiß, dass diese Operatoren implizit auf der Basis des aufgezählten Typs erstellt wurden (wie in der documentation), aber ich möchte diese Operatoren explizit definieren (zur Klarheit, zur Kontrolle, um zu wissen, wie es geht, etc ...)Wie überlade ich einen Operator für eine Aufzählung in C#?

ich hatte gehofft, ich so etwas wie tun könnte:

public enum SizeType 
{ 
    Small = 0, 
    Medium = 1, 
    Large = 2, 
    ExtraLarge = 3 
} 

public SizeType operator >(SizeType x, SizeType y) 
{ 

} 

Aber diese („unexpected toke“) nicht mehr zu funktionieren scheint ... ist das möglich? Es scheint, dass es sein sollte, da es implizit definierte Operatoren gibt. Irgendwelche Vorschläge?

Antwort

31

Sie können das nicht tun. Sie können nur überladene Operatoren für Klassen und Strukturen bereitstellen, die Sie definieren - und mindestens einer der Parameter sollte vom Typ der Klasse oder Struktur selbst sein. Das heißt, Sie können einen überladenen Additionsoperator deklarieren, der MyClass zu MyEnum hinzufügt, aber Sie können das nie mit zwei MyEnum Werten tun.

+0

dass disapointing ist, wie tun sie das implizit dann? Es schien, als würde es keinen Weg geben, aber ich dachte, wenn du es implizit tun könntest, dann sollte es einen Weg geben, es explizit zu tun. Ich denke nicht. Danke für die Information. – ChrisHDog

+0

Sie nicht. Es gibt auch keinen * impliziten * Weg. Sie können Operatoren einfach nicht für Enums überladen. –

+0

Entsprechend: http://msdn.microsoft.com/en-us/library/aa664726(VS.71).aspx ... "Jeder Aufzählungstyp stellt implizit die folgenden vordefinierten Vergleichsoperatoren bereit:" ... Ich war gerade in der Hoffnung, dass es einen Weg gibt, einen Vergleichsoperator in ähnlicher Weise explizit bereitzustellen. Also kein Overload-Operator, sondern etwas ähnliches. – ChrisHDog

11

Wie Mehrdad sagt, können Sie das nicht auf dem Enum selbst tun. Sie können jedoch einige Erweiterungsmethoden verwenden, die an Ihrer Enumeration arbeiten. Das wird es wie Methoden auf dem Enum aussehen lassen.

20

Wie bereits erwähnt, kann man Operatoren auf Enums nicht überschreiben, aber Sie können es auf struct tun. Siehe ein Beispiel unten. Lassen Sie mich wissen, ob es geholfen:

public struct SizeType 
{ 
    private int InternalValue { get; set; } 

    public static readonly int Small = 0; 
    public static readonly int Medium = 1; 
    public static readonly int Large = 2; 
    public static readonly int ExtraLarge = 3; 

    public override bool Equals(object obj) 
    { 
     SizeType otherObj = (SizeType)obj; 
     return otherObj.InternalValue.Equals(this.InternalValue); 
    } 

    public static bool operator >(SizeType left, SizeType right) 
    { 
     return (left.InternalValue > right.InternalValue); 
    } 

    public static implicit operator SizeType(int otherType) 
    { 
     return new SizeType 
     { 
      InternalValue = otherType 
     }; 
    } 
} 

public class test11 
{ 
    void myTest() 
    { 
     SizeType smallSize = SizeType.Small; 
     SizeType largeType = SizeType.Large; 
     if (smallSize > largeType) 
     { 
      Console.WriteLine("small is greater than large"); 
     } 
    } 
} 
+0

Eine Enumeration kann in einer switch-Anweisung verwendet werden, während eine Struktur nicht. –

+0

@MikedeKlerk das halb-geändert in C# 7.0 https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/ – MaLiN2223

16

Nach ECMA-335 Common Language Infrastructure:

The CTS supports an enum (also known as an enumeration type), an alternate name for an existing type. For the purposes of matching signatures, an enum shall not be the same as the underlying type. Instances of an enum, however, shall be assignable-to the underlying type, and vice versa. That is, no cast (see §8.3.3) or coercion (see §8.3.2) is required to convert from the enum to the underlying type, nor are they required from the underlying type to the enum. An enum is considerably more restricted than a true type, as follows: It shall have exactly one instance field, and the type of that field defines the underlying type of the enumeration.

  • It shall not have any methods of its own.
  • It shall derive from System.Enum (see Partition IV Library – Kernel Package).
  • It shall not implement any interfaces of its own.
  • It shall not have any properties or events of its own.
  • It shall not have any static fields unless they are literal. (see §8.6.1.2)

Nehmen wir an, dass wir folgende IL-Code haben:

.class public auto ansi sealed Test.Months extends [mscorlib]System.Enum 
{ 
    .field public specialname rtspecialname int32 value__ 
    .field public static literal valuetype Test.Months January = int32(0x00000001) 
    .field public static literal valuetype Test.Months February = int32(0x00000002) 
    .field public static literal valuetype Test.Months March = int32(0x00000003) 
    // ... 

    .method public hidebysig specialname static valuetype Test.Months 
    op_Increment(valuetype Test.Months m) cil managed 
    { 
    .maxstack 8 

    IL_0000: ldarg.0 
    IL_0001: ldc.i4.s 10 
    IL_0003: add 
    IL_0004: ret 
    } 
} // end of class Test.Months 

MSIL Compiler (ilasm.exe) erzeugt folgenden Fehler:

error -- Method in enum 
***** FAILURE *****

So können wir nicht Enum Betreiber Überlastung auch IL-Code Bearbeitung;)

+0

Wertvolle Informationen! –

3

Sie können nicht die compareTo-Methode überschreiben, aber Sie können eine Erweiterungsmethode hinzufügen:

<Runtime.CompilerServices.Extension()> 
Public Function Compare(ByVal obj1 As EnumType, ByVal obj2 As EnumType) as integer 
    Dim CompareResults as integer = 0 
    'some code here to do your comparison 
    Return CompareResults 
End Sub 

Und dann ist es wie folgt ausführen :

IntegerResult = myEnum.Compare(otherEnum) 

Von http://msdn.microsoft.com/en-us/library/bb384936.aspx