簡體   English   中英

如何在C#中重載運算符以進行枚舉?

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

我有一個枚舉類型,我想為其定義><>=<=運算符。 我知道這些運算符是根據枚舉類型(根據文檔 )隱式創建的,但是我想明確定義這些運算符(為清楚起見,進行控制,知道如何執行操作等)。

我希望可以做類似的事情:

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

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

}

但這似乎不起作用(“意外令牌”)...這可能嗎? 似乎應該這樣,因為存在隱式定義的運算符。 有什么建議么?

你不能那樣做。 您只能為您定義的類和結構提供重載運算符-並且至少一個參數應為類或結構本身的類型。 也就是說,您可以聲明一個重載加法運算符,該運算符將MyClass添加到MyEnum但是永遠不能使用兩個MyEnum值來執行此操作。

如前所述,您不能在Enums上覆蓋運算符,但是您可以在struct上做到。 請參閱下面的示例。 讓我知道是否有幫助:

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

根據ECMA-335公共語言基礎架構:

CTS支持枚舉(也稱為枚舉類型),是現有類型的備用名稱。 為了匹配簽名,枚舉不得與基礎類型相同。 但是,枚舉的實例應可分配給基礎類型,反之亦然。 也就是說,從枚舉轉換為基礎類型不需要強制轉換(請參見第8.3.3節)或強制轉換(請參見第8.3.2節),也不需要從基礎類型轉換為枚舉。 枚舉比真實類型要嚴格得多,如下所示:枚舉應僅具有一個實例字段,並且該字段的類型定義枚舉的基礎類型。

  • 它不能有任何自己的方法。
  • 它應從System.Enum派生(請參閱分區IV庫–內核程序包)。
  • 它不應實現自己的任何接口。
  • 它不具有任何屬性或事件。
  • 除非它們是文字,否則它不應有任何靜態字段。 (請參見第8.6.1.2節)

假設我們有以下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編譯器(ilasm.exe)將生成以下錯誤:

  錯誤-枚舉中的方法\n *****失敗***** 

因此,即使編輯IL代碼,我們也無法重載枚舉運算符;)

正如Mehrdad所說,您不能在枚舉本身上做到這一點。 但是,您可以使用幾種適用於枚舉的擴展方法。 這將使其看起來像枚舉上的方法。

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

您不能覆蓋compareto方法,但是可以添加擴展方法:

<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

然后執行如下:

IntegerResult = myEnum.Compare(otherEnum)

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM