2009-08-31 42 views
29

Tôi có một loại được liệt kê mà tôi muốn xác định các toán tử>, <,> = và < = cho. Tôi biết rằng các toán tử này được tạo ra dựa trên kiểu liệt kê (theo số documentation) nhưng tôi muốn xác định rõ ràng các toán tử này (để làm rõ, kiểm soát, biết cách thực hiện, vv ...)Làm cách nào để quá tải một toán tử cho một liệt kê trong C#?

tôi đã hy vọng tôi có thể làm một cái gì đó như:

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

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

} 

Nhưng điều này dường như không làm việc ("Toke bất ngờ") ... có thể như vậy? Nó có vẻ như nó nên được kể từ khi có các nhà khai thác được xác định rõ ràng. Bất kỳ đề xuất?

Trả lời

31

Bạn không thể làm điều đó. Bạn chỉ có thể cung cấp các toán tử quá tải cho các lớp và các cấu trúc mà bạn định nghĩa - và ít nhất một trong các tham số phải thuộc kiểu của lớp hoặc cấu trúc. Tức là, bạn có thể khai báo toán tử cộng chồng quá tải thêm MyClass thành MyEnum nhưng bạn không bao giờ có thể làm điều đó với hai giá trị MyEnum.

+0

đó là disapointing, làm thế nào để họ làm điều đó implictly sau đó? Có vẻ như sẽ không có cách nào, nhưng tôi nghĩ nếu bạn có thể làm điều đó một cách ngầm định thì sẽ có một cách để làm điều đó một cách rõ ràng. Tôi đoán là không. Cảm ơn vì thông tin. – ChrisHDog

+0

Họ không. Không có cách nào * ngầm định *. Bạn chỉ đơn giản là không thể quá tải các nhà khai thác cho enums. –

+0

Theo: http://msdn.microsoft.com/en-us/library/aa664726(VS.71).aspx ... "Mỗi kiểu liệt kê ngầm cung cấp các toán tử so sánh được xác định trước:" ... Tôi chỉ là hy vọng có một cách để cung cấp một cách rõ ràng một toán tử so sánh tương tự. Vì vậy, không phải là một nhà điều hành quá tải chính xác, nhưng một cái gì đó simlar. – ChrisHDog

11

Như Mehrdad nói, bạn không thể làm điều đó trên chính bản thân enum. Tuy nhiên bạn có thể thực hiện một vài phương pháp mở rộng làm việc trên enum của bạn. Điều đó sẽ làm cho nó trông giống như phương pháp trên enum.

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

Như đã đề cập trước đây, người ta không thể ghi đè toán tử trên Enums, nhưng bạn có thể thực hiện trên cấu trúc. Xem ví dụ bên dưới. Hãy cho tôi biết nếu nó giúp:

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

Một enum có thể được sử dụng trong một câu lệnh switch trong khi struct không thể. –

+0

@MikedeKlerk này được bán thay đổi trong C# 7.0 https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/ – MaLiN2223

16

Theo Cơ sở hạ tầng 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)

Giả sử rằng chúng tôi đã có sau mã 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 trình biên dịch (ilasm.exe) sẽ tạo ra lỗi sau:

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

Vì vậy, chúng ta không thể quá tải toán tử enum thậm chí chỉnh sửa mã IL;)

+0

Thông tin có giá trị! –

3

Bạn không có thể ghi đè các phương thức compareTo, nhưng bạn có thể thêm một phương pháp khuyến nông:

<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 

Và sau đó thực hiện nó như sau :

IntegerResult = myEnum.Compare(otherEnum) 

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

Các vấn đề liên quan