2009-08-31 10 views
29

que tienen un tipo enumerado que me gustaría definir la>, <,> = y = < operadores para. Sé que estos operadores se crean implícitamente sobre la base del tipo enumerado (según la documentation) pero me gustaría definir explicitamente estos operadores (para mayor claridad, para el control, para saber cómo hacerlo, etc ...)¿Cómo sobrecargo un operador para una enumeración en C#?

Tenía la esperanza de que pudiera hacer algo como:

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

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

} 

Pero esto no parece funcionar ("toke inesperada") ... ¿es esto posible? Parece que debería ser así porque hay operadores definidos implícitamente. ¿Alguna sugerencia?

Respuesta

31

No se puede hacer eso. Solo puede proporcionar operadores sobrecargados para las clases y estructuras que defina, y al menos uno de los parámetros debe ser del tipo de la clase o estructura en sí. Es decir, se puede declarar un operador de suma sobrecargado que añade un MyClass-MyEnum pero nunca se puede hacer eso con dos MyEnum valores.

+0

eso es decepcionante, ¿cómo lo hacen implícitamente que entonces? Parecía que no habría una manera, pero pensé que si podías hacerlo implícitamente, entonces debería haber una forma de hacerlo explícitamente. Supongo que no. Gracias por la información. – ChrisHDog

+0

No lo hacen. Tampoco hay una forma * implícita *. Simplemente no puede sobrecargar operadores para enums. De acuerdo con –

+0

: http://msdn.microsoft.com/en-us/library/aa664726(VS.71).aspx ... "Cada tipo de enumeración implícita proporciona los siguientes operadores de comparación predefinidos:" ... yo era sólo esperando que haya una forma de proporcionar explícitamente un operador de comparación de manera similar. Entonces no es exactamente un operador de sobrecarga, sino algo similar. – ChrisHDog

11

como dice Mehrdad, no se puede hacer eso en la propia enumeración. Sin embargo, puedes hacer un par de métodos de extensión que funcionen en tu enumeración. Eso hará que se vea como métodos en la enumeración.

static bool IsLessThan(this SizeType first, SizeType second) { 
} 
20

Como se mencionó anteriormente, no se pueden anular los operadores en los Enums, pero puede hacerlo en struct. Vea un ejemplo a continuación. Que me haga saber si ayudó:

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

Una enumeración se puede utilizar en una instrucción de cambio mientras que una estructura no. –

+0

@MikedeKlerk esta semi-cambiado en C# 7.0 https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/ – MaLiN2223

16

Según Infraestructura ECMA-335 Common Language:

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)

Asumamos que tenemos siguiente código IL:

.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 compilador (ilasm.exe) generará el siguiente error:

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

Así que no podemos sobrecargar el operador enumeración incluso la edición de código IL;)

+0

¡Información valiosa! –

3

No se puede reemplazar el método compareTo, pero se puede añadir un método de extensión:

<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 

Y luego ejecutarlo de la siguiente :

IntegerResult = myEnum.Compare(otherEnum) 

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

Cuestiones relacionadas