繁体   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