How do I overload an operator for an enumeration in C#?

29,461

Solution 1

You can't do that. You can only provide overloaded operators for classes and structs you define -- and at least one of the parameters should be of type of the class or struct itself. That is, you can declare an overloaded addition operator that adds a MyClass to MyEnum but you can never do that with two MyEnum values.

Solution 2

As other mentioned before, one cannot override operators on Enums, but you can do it on struct. See an example below. Let me know if it helped:

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 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");
        }
    }
}

Solution 3

According to 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)

Let's assume that we've got following IL code:

.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) will generate following error:

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

So we can't overload enum operator even editing IL code ;)

Solution 4

As Mehrdad says, you can't do that on the enum itself. You could however make a couple of extension methods that work on your enum. That will make it look like methods on the enum.

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

Solution 5

You can't override the compareto method, but you can add an extension method:

<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

And then execute it as follows:

IntegerResult = myEnum.Compare(otherEnum)

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

Share:
29,461
user2571901
Author by

user2571901

Your standard software developer

Updated on July 24, 2022

Comments

  • user2571901
    user2571901 almost 2 years

    I have an enumerated type that I would like to define the >, <, >=, and <= operators for. I know that these operators are implictly created on the basis of the enumerated type (as per the documentation) but I would like to explictly define these operators (for clarity, for control, to know how to do it, etc...)

    I was hoping I could do something like:

    public enum SizeType
    {
        Small = 0,
        Medium = 1,
        Large = 2,
        ExtraLarge = 3
    }
    
    public SizeType operator >(SizeType x, SizeType y)
    {
    
    }
    

    But this doesn't seem to work ("unexpected token") ... is this possible? It seems like it should be since there are implictly defined operators. Any suggestions?

  • user2571901
    user2571901 over 14 years
    That is disapointing, how do they do that implictly then? It seemed like there wouldn't be a way, but I figured if you could do it implicitly then there should be a way to do it explictly. I guess not. Thanks for the information.
  • mmx
    mmx over 14 years
    They don't. There's no implicit way either. You simply can't overload operators for enums.
  • user2571901
    user2571901 over 14 years
    According to: msdn.microsoft.com/en-us/library/aa664726(VS.71).aspx ... "Every enumeration type implicitly provides the following predefined comparison operators:" ... I was just hoping there was a way to explicitly provide a comparison operator similarly. So not an overload operator exactly, but something simlar.
  • mmx
    mmx over 14 years
    Aha. I thought you mean you can implement an implicit operator for enum. The key word in the statement you referred to is predefined. The thing is, you can't define any custom operator implementations for enums.
  • Mike de Klerk
    Mike de Klerk about 7 years
    An enum can be used in a switch statement whereas a struct can not.
  • MaLiN2223
    MaLiN2223 over 6 years
    @MikedeKlerk this semi-changed in C# 7.0 blogs.msdn.microsoft.com/dotnet/2016/08/24/…
  • Robbie
    Robbie almost 3 years
    Well this was an annoying bug to find.