如何在C#中为运算符重载运算符?

时间:2009-08-31 04:41:57

标签: c# enums operators operator-overloading

我有一个枚举类型,我想为><>=<=运算符定义。我知道这些运算符是基于枚举类型隐含创建的(根据documentation)但我想明确定义这些运算符(为了清晰,控制,知道如何操作等等)。 ..)

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

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

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

}

但这似乎不起作用(“意外令牌”)......这可能吗?它似乎应该是因为有隐含定义的运算符。有什么建议吗?

5 个答案:

答案 0 :(得分:32)

你做不到。您只能为您定义的类和结构提供重载运算符 - 并且至少有一个参数应该是类或结构本身的类型。也就是说,你可以声明一个重载的加法运算符,它将MyClass添加到MyEnum,但你永远不能用两个MyEnum值来做。

答案 1 :(得分:23)

如前所述,人们不能覆盖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");
        }
    }
}

答案 2 :(得分:17)

根据ECMA-335共同语言基础设施:

  

CTS支持枚举(也称为枚举类型),a   现有类型的备用名称。出于匹配的目的   签名,枚举不得与基础类型相同。   然而,枚举的实例应该可分配给底层实例   类型,反之亦然。也就是说,没有演员阵容(见§8.3.3)或强制(见   §8.3.2)需要从枚举转换为基础类型,   它们也不需要从基础类型到枚举。一个枚举是   比真实类型更受限制,如下:它应该   只有一个实例字段,该字段的类型定义   枚举的基础类型。

     
      
  • 它不应该有任何方法。
  •   
  • 它应来自System.Enum(参见Partition IV Library - Kernel Package)。
  •   
  • 它不应该实现它自己的任何接口。
  •   
  • 不得有任何属性或事件。
  •   
  • 除非是文字,否则它不应有任何静态字段。 (见§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)将生成以下错误:

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

因此我们不能重载枚举运算符甚至编辑IL代码;)

答案 3 :(得分:11)

正如Mehrdad所说,你不能在枚举本身上做到这一点。但是,您可以制作一些适用于枚举的扩展方法。这将使它看起来像枚举上的方法。

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

答案 4 :(得分:3)

您无法覆盖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