Kelas System.Enum

Artikel ini menyediakan keterangan tambahan untuk dokumentasi referensi untuk API ini.

Enumerasi adalah sekumpulan konstanta bernama yang jenis yang mendasarnya adalah jenis integral apa pun. Jika tidak ada jenis yang mendasar yang dideklarasikan secara eksplisit, Int32 digunakan. Enum adalah kelas dasar untuk semua enumerasi di .NET. Jenis enumerasi didefinisikan oleh enum kata kunci di C#, Enumkonstruksi ...End Enum di Visual Basic, dan type kata kunci di F#.

Enum menyediakan metode untuk membandingkan instans kelas ini, mengonversi nilai instans ke representasi stringnya, mengonversi representasi string dari angka menjadi instans kelas ini, dan membuat instans enumerasi dan nilai tertentu.

Anda juga dapat memperlakukan enumerasi sebagai bidang bit. Untuk informasi selengkapnya, lihat bagian Anggota non-eksklusif dan atribut Bendera dan FlagsAttribute.

Membuat jenis enumerasi

Bahasa pemrograman biasanya menyediakan sintaksis untuk mendeklarasikan enumerasi yang terdiri dari sekumpulan konstanta bernama dan nilainya. Contoh berikut mengilustrasikan sintaks yang digunakan oleh C#, F#, dan Visual Basic untuk menentukan enumerasi. Ini membuat enumerasi bernama ArrivalStatus yang memiliki tiga anggota: ArrivalStatus.Early, ArrivalStatus.OnTime, dan ArrivalStatus.Late. Perhatikan bahwa dalam semua kasus, enumerasi tidak secara eksplisit mewarisi dari Enum; hubungan warisan ditangani secara implisit oleh kompilator.

public enum ArrivalStatus { Unknown=-3, Late=-1, OnTime=0, Early=1 };
type ArrivalStatus =
    | Late = -1
    | OnTime = 0
    | Early = 1
Public Enum ArrivalStatus1 As Integer
    Late = -1
    OnTime = 0
    Early = 1
End Enum

Peringatan

Anda tidak boleh membuat jenis enumerasi yang jenis yang mendasarnya non-integral atau Char. Meskipun Anda dapat membuat jenis enumerasi seperti itu dengan menggunakan pantulan, panggilan metode yang menggunakan jenis yang dihasilkan tidak dapat diandalkan dan juga dapat melemparkan pengecualian tambahan.

Membuat instans jenis enumerasi

Anda dapat membuat instans jenis enumerasi sama seperti Anda membuat instans jenis nilai lain: dengan mendeklarasikan variabel dan menetapkan salah satu konstanta enumerasi ke dalamnya. Contoh berikut membuat instans nilainya ArrivalStatus adalah ArrivalStatus.OnTime.

public class Example
{
   public static void Main()
   {
      ArrivalStatus status = ArrivalStatus.OnTime;
      Console.WriteLine("Arrival Status: {0} ({0:D})", status);
   }
}
// The example displays the following output:
//       Arrival Status: OnTime (0)
let status = ArrivalStatus.OnTime
printfn $"Arrival Status: {status} ({status:D})"
// The example displays the following output:
//       Arrival Status: OnTime (0)
Public Module Example1
    Public Sub Main()
        Dim status As ArrivalStatus1 = ArrivalStatus1.OnTime
        Console.WriteLine("Arrival Status: {0} ({0:D})", status)
    End Sub
End Module
' The example displays the following output:
'        Arrival Status: OnTime (0)

Anda juga dapat membuat contoh nilai enumerasi dengan cara berikut:

  • Dengan menggunakan fitur bahasa pemrograman tertentu untuk dilemparkan (seperti dalam C#) atau mengonversi (seperti dalam Visual Basic) nilai bilangan bulat menjadi nilai enumerasi. Contoh berikut membuat objek yang ArrivalStatus nilainya dengan ArrivalStatus.Early cara ini.

    ArrivalStatus status2 = (ArrivalStatus)1;
    Console.WriteLine("Arrival Status: {0} ({0:D})", status2);
    // The example displays the following output:
    //       Arrival Status: Early (1)
    
    let status2 = enum<ArrivalStatus> 1
    printfn $"Arrival Status: {status2} ({status2:D})"
    // The example displays the following output:
    //       Arrival Status: Early (1)
    
    Dim status2 As ArrivalStatus2 = CType(1, ArrivalStatus2)
    Console.WriteLine("Arrival Status: {0} ({0:D})", status2)
    ' The example displays the following output:
    '       Arrival Status: Early (1)
    
  • Dengan memanggil konstruktor tanpa parameter implisitnya. Seperti yang ditunjukkan contoh berikut, dalam hal ini nilai yang mendasar dari instans enumerasi adalah 0. Namun, ini belum tentu nilai konstanta yang valid dalam enumerasi.

    ArrivalStatus status1 = new ArrivalStatus();
    Console.WriteLine("Arrival Status: {0} ({0:D})", status1);
    // The example displays the following output:
    //       Arrival Status: OnTime (0)
    
    let status1 = ArrivalStatus()
    printfn $"Arrival Status: {status1} ({status1:D})"
    // The example displays the following output:
    //       Arrival Status: OnTime (0)
    
    Dim status1 As New ArrivalStatus2()
    Console.WriteLine("Arrival Status: {0} ({0:D})", status1)
    ' The example displays the following output:
    '        Arrival Status: OnTime (0)
    
  • Dengan memanggil Parse metode atau TryParse untuk mengurai string yang berisi nama konstanta dalam enumerasi. Untuk informasi selengkapnya, lihat bagian Mengurai nilai enumerasi.

  • Dengan memanggil ToObject metode untuk mengonversi nilai integral ke jenis enumerasi. Untuk informasi selengkapnya, lihat bagian Melakukan konversi .

Praktik terbaik enumerasi

Kami menyarankan agar Anda menggunakan praktik terbaik berikut saat menentukan jenis enumerasi:

  • Jika Anda belum menentukan anggota enumerasi yang nilainya adalah 0, pertimbangkan untuk None membuat konstanta enumerasi. Secara default, memori yang digunakan untuk enumerasi diinisialisasi ke nol oleh runtime bahasa umum. Akibatnya, jika Anda tidak menentukan konstanta yang nilainya nol, enumerasi akan berisi nilai ilegal saat dibuat.

  • Jika ada kasus default yang jelas yang harus diwakili aplikasi Anda, pertimbangkan untuk menggunakan konstanta enumerasi yang nilainya nol untuk mewakilinya. Jika tidak ada kasus default, pertimbangkan untuk menggunakan konstanta enumerasi yang nilainya nol untuk menentukan kasus yang tidak diwakili oleh konstanta enumerasi lainnya.

  • Jangan tentukan konstanta enumerasi yang dicadangkan untuk digunakan di masa mendatang.

  • Saat Anda menentukan metode atau properti yang mengambil konstanta enumerasi sebagai nilai, pertimbangkan untuk memvalidasi nilai. Alasannya adalah Anda dapat melemparkan nilai numerik ke jenis enumerasi bahkan jika nilai numerik tersebut tidak ditentukan dalam enumerasi.

Praktik terbaik tambahan untuk jenis enumerasi yang konstantanya adalah bidang bit tercantum di anggota Non-eksklusif dan bagian atribut Bendera.

Melakukan operasi dengan enumerasi

Anda tidak dapat menentukan metode baru saat membuat enumerasi. Namun, jenis enumerasi mewarisi sekumpulan lengkap metode statis dan instans dari Enum kelas . Bagian berikut mensurvei sebagian besar metode ini, selain beberapa metode lain yang umumnya digunakan saat bekerja dengan nilai enumerasi.

Melakukan konversi

Anda dapat mengonversi antara anggota enumerasi dan jenis yang mendasarnya dengan menggunakan transmisi (di C# dan F#), atau operator konversi (di Visual Basic). Di F#, enum fungsi juga digunakan. Contoh berikut menggunakan operator transmisi atau konversi untuk melakukan konversi baik dari bilangan bulat ke nilai enumerasi dan dari nilai enumerasi ke bilangan bulat.

int value3 = 2;
ArrivalStatus status3 = (ArrivalStatus)value3;

int value4 = (int)status3;
let value3 = 2
let status3 = enum<ArrivalStatus> value3

let value4 = int status3
Dim value3 As Integer = 2
Dim status3 As ArrivalStatus2 = CType(value3, ArrivalStatus2)

Dim value4 As Integer = CInt(status3)

Kelas ini Enum juga menyertakan ToObject metode yang mengonversi nilai dari jenis integral apa pun menjadi nilai enumerasi. Contoh berikut menggunakan ToObject(Type, Int32) metode untuk mengonversi ke Int32ArrivalStatus nilai. Perhatikan bahwa, karena ToObject mengembalikan nilai jenis Object, penggunaan operator transmisi atau konversi mungkin masih diperlukan untuk mentransmisikan objek ke jenis enumerasi.

int number = -1;
ArrivalStatus arrived = (ArrivalStatus)ArrivalStatus.ToObject(typeof(ArrivalStatus), number);
let number = -1
let arrived = ArrivalStatus.ToObject(typeof<ArrivalStatus>, number) :?> ArrivalStatus
Dim number As Integer = -1
Dim arrived As ArrivalStatus2 = CType(ArrivalStatus2.ToObject(GetType(ArrivalStatus2), number), ArrivalStatus2)

Saat mengonversi bilangan bulat menjadi nilai enumerasi, dimungkinkan untuk menetapkan nilai yang sebenarnya bukan anggota enumerasi. Untuk mencegah hal ini, Anda dapat meneruskan bilangan bulat ke IsDefined metode sebelum melakukan konversi. Contoh berikut menggunakan metode ini untuk menentukan apakah elemen dalam array nilai bilangan bulat dapat dikonversi ke ArrivalStatus nilai.

using System;

public class Example3
{
    public static void Main()
    {
        int[] values = { -3, -1, 0, 1, 5, Int32.MaxValue };
        foreach (var value in values)
        {
            ArrivalStatus status;
            if (Enum.IsDefined(typeof(ArrivalStatus), value))
                status = (ArrivalStatus)value;
            else
                status = ArrivalStatus.Unknown;
            Console.WriteLine("Converted {0:N0} to {1}", value, status);
        }
    }
}
// The example displays the following output:
//       Converted -3 to Unknown
//       Converted -1 to Late
//       Converted 0 to OnTime
//       Converted 1 to Early
//       Converted 5 to Unknown
//       Converted 2,147,483,647 to Unknown
open System

type ArrivalStatus =
    | Unknown = -3
    | Late = -1
    | OnTime = 0
    | Early = 1

let values = [ -3; -1; 0; 1; 5; Int32.MaxValue ]
for value in values do
    let status =
        if Enum.IsDefined(typeof<ArrivalStatus>, value) then
            enum value
        else
            ArrivalStatus.Unknown
    printfn $"Converted {value:N0} to {status}"
// The example displays the following output:
//       Converted -3 to Unknown
//       Converted -1 to Late
//       Converted 0 to OnTime
//       Converted 1 to Early
//       Converted 5 to Unknown
//       Converted 2,147,483,647 to Unknown
Public Enum ArrivalStatus4 As Integer
    Unknown = -3
    Late = -1
    OnTime = 0
    Early = 1
End Enum

Module Example4
    Public Sub Main()
        Dim values() As Integer = {-3, -1, 0, 1, 5, Int32.MaxValue}
        For Each value In values
            Dim status As ArrivalStatus4
            If [Enum].IsDefined(GetType(ArrivalStatus4), value) Then
                status = CType(value, ArrivalStatus4)
            Else
                status = ArrivalStatus4.Unknown
            End If
            Console.WriteLine("Converted {0:N0} to {1}", value, status)
        Next
    End Sub
End Module
' The example displays the following output:
'       Converted -3 to Unknown
'       Converted -1 to Late
'       Converted 0 to OnTime
'       Converted 1 to Early
'       Converted 5 to Unknown
'       Converted 2,147,483,647 to Unknown

Enum Meskipun kelas menyediakan implementasi antarmuka eksplisit antarmuka IConvertible untuk mengonversi dari nilai enumerasi ke jenis integral, Anda harus menggunakan metode Convert kelas, seperti ToInt32, untuk melakukan konversi ini. Contoh berikut menggambarkan bagaimana Anda dapat menggunakan GetUnderlyingType metode bersama dengan Convert.ChangeType metode untuk mengonversi nilai enumerasi ke jenis yang mendasarnya. Perhatikan bahwa contoh ini tidak memerlukan jenis enumerasi yang mendasar untuk diketahui pada waktu kompilasi.

ArrivalStatus status = ArrivalStatus.Early;
var number = Convert.ChangeType(status, Enum.GetUnderlyingType(typeof(ArrivalStatus)));
Console.WriteLine("Converted {0} to {1}", status, number);
// The example displays the following output:
//       Converted Early to 1
let status = ArrivalStatus.Early
let number = Convert.ChangeType(status, Enum.GetUnderlyingType typeof<ArrivalStatus>)
printfn $"Converted {status} to {number}"
// The example displays the following output:
//       Converted Early to 1
Dim status As ArrivalStatus5 = ArrivalStatus5.Early
Dim number = Convert.ChangeType(status, [Enum].GetUnderlyingType(GetType(ArrivalStatus5)))
Console.WriteLine("Converted {0} to {1}", status, number)
' The example displays the following output:
'       Converted Early to 1

Mengurai nilai enumerasi

Metode Parse dan TryParse memungkinkan Anda mengonversi representasi string dari nilai enumerasi ke nilai tersebut. Representasi string dapat berupa nama atau nilai yang mendasar dari konstanta enumerasi. Perhatikan bahwa metode penguraian akan berhasil mengonversi representasi string angka yang bukan anggota enumerasi tertentu jika string dapat dikonversi ke nilai jenis enumerasi yang mendasar. Untuk mencegah hal ini, IsDefined metode dapat dipanggil untuk memastikan bahwa hasil metode penguraian adalah nilai enumerasi yang valid. Contoh mengilustrasikan pendekatan ini dan menunjukkan panggilan ke Parse(Type, String) metode dan Enum.TryParse<TEnum>(String, TEnum) . Perhatikan bahwa metode penguraian non-generik mengembalikan objek yang mungkin harus Anda berikan (di C# dan F#) atau mengonversi (di Visual Basic) ke jenis enumerasi yang sesuai.

string number = "-1";
string name = "Early";

try
{
    ArrivalStatus status1 = (ArrivalStatus)Enum.Parse(typeof(ArrivalStatus), number);
    if (!(Enum.IsDefined(typeof(ArrivalStatus), status1)))
        status1 = ArrivalStatus.Unknown;
    Console.WriteLine("Converted '{0}' to {1}", number, status1);
}
catch (FormatException)
{
    Console.WriteLine("Unable to convert '{0}' to an ArrivalStatus value.",
                      number);
}

ArrivalStatus status2;
if (Enum.TryParse<ArrivalStatus>(name, out status2))
{
    if (!(Enum.IsDefined(typeof(ArrivalStatus), status2)))
        status2 = ArrivalStatus.Unknown;
    Console.WriteLine("Converted '{0}' to {1}", name, status2);
}
else
{
    Console.WriteLine("Unable to convert '{0}' to an ArrivalStatus value.",
                      number);
}
// The example displays the following output:
//       Converted '-1' to Late
//       Converted 'Early' to Early
let number = "-1"
let name = "Early"

try
    let status1 = Enum.Parse(typeof<ArrivalStatus>, number) :?> ArrivalStatus
    let status1 =
        if not (Enum.IsDefined(typeof<ArrivalStatus>, status1) ) then
            ArrivalStatus.Unknown
        else 
            status1
        
    printfn $"Converted '{number}' to {status1}"
with :? FormatException ->
    printfn $"Unable to convert '{number}' to an ArrivalStatus value."

match Enum.TryParse<ArrivalStatus> name with
| true, status2 ->
    let status2 = 
        if not (Enum.IsDefined(typeof<ArrivalStatus>, status2) ) then
            ArrivalStatus.Unknown
        else 
            status2
    printfn $"Converted '{name}' to {status2}"
| _ ->
    printfn $"Unable to convert '{number}' to an ArrivalStatus value."
// The example displays the following output:
//       Converted '-1' to Late
//       Converted 'Early' to Early
Dim number As String = "-1"
Dim name As String = "Early"
Dim invalid As String = "32"

Try
    Dim status1 As ArrivalStatus8 = CType([Enum].Parse(GetType(ArrivalStatus8), number), ArrivalStatus8)
    If Not [Enum].IsDefined(GetType(ArrivalStatus8), status1) Then status1 = ArrivalStatus8.Unknown
    Console.WriteLine("Converted '{0}' to {1}", number, status1)
Catch e As FormatException
    Console.WriteLine("Unable to convert '{0}' to an ArrivalStatus8 value.",
                   number)
End Try

Dim status2 As ArrivalStatus8
If [Enum].TryParse(Of ArrivalStatus8)(name, status2) Then
    If Not [Enum].IsDefined(GetType(ArrivalStatus8), status2) Then status2 = ArrivalStatus8.Unknown
    Console.WriteLine("Converted '{0}' to {1}", name, status2)
Else
    Console.WriteLine("Unable to convert '{0}' to an ArrivalStatus8 value.",
                   number)
End If
' The example displays the following output:
'       Converted '-1' to Late
'       Converted 'Early' to Early

Format nilai enumerasi

Anda dapat mengonversi nilai enumerasi ke representasi string mereka dengan memanggil metode statis Format , serta kelebihan beban metode instans ToString . Anda dapat menggunakan string format untuk mengontrol cara yang tepat di mana nilai enumerasi diwakili sebagai string. Untuk informasi selengkapnya, lihat String Format Enumerasi. Contoh berikut menggunakan masing-masing string format enumerasi yang didukung ("G" atau "g", "D" atau "d", "X" atau "x", dan "F" atau "f" ) untuk mengonversi anggota ArrivalStatus enumerasi ke representasi stringnya.

string[] formats = { "G", "F", "D", "X" };
ArrivalStatus status = ArrivalStatus.Late;
foreach (var fmt in formats)
    Console.WriteLine(status.ToString(fmt));

// The example displays the following output:
//       Late
//       Late
//       -1
//       FFFFFFFF
let formats = [ "G"; "F"; "D"; "X" ]
let status = ArrivalStatus.Late
for fmt in formats do
    printfn $"{status.ToString fmt}"

// The example displays the following output:
//       Late
//       Late
//       -1
//       FFFFFFFF
Dim formats() As String = {"G", "F", "D", "X"}
Dim status As ArrivalStatus6 = ArrivalStatus6.Late
For Each fmt As String In formats
    Console.WriteLine(status.ToString(fmt))
Next
' The example displays the following output:
'       Late
'       Late
'       -1
'       FFFFFFFF

Iterasi anggota enumerasi

Enum Jenis tidak mengimplementasikan IEnumerable antarmuka atau IEnumerable<T> , yang akan memungkinkan Anda untuk melakukan iterasi anggota koleksi dengan menggunakan foreach konstruksi (dalam C#), for..in (di F#), atau For Each (di Visual Basic). Namun, Anda dapat menghitung anggota dengan salah satu dari dua cara.

  • Anda dapat memanggil GetNames metode untuk mengambil array string yang berisi nama anggota enumerasi. Selanjutnya, untuk setiap elemen array string, Anda dapat memanggil Parse metode untuk mengonversi string ke nilai enumerasi yang setara. Contoh berikut menggambarkan pendekatan ini.

    string[] names = Enum.GetNames(typeof(ArrivalStatus));
    Console.WriteLine("Members of {0}:", typeof(ArrivalStatus).Name);
    Array.Sort(names);
    foreach (var name in names)
    {
        ArrivalStatus status = (ArrivalStatus)Enum.Parse(typeof(ArrivalStatus), name);
        Console.WriteLine("   {0} ({0:D})", status);
    }
    // The example displays the following output:
    //       Members of ArrivalStatus:
    //          Early (1)
    //          Late (-1)
    //          OnTime (0)
    //          Unknown (-3)
    
    let names = Enum.GetNames typeof<ArrivalStatus>
    printfn $"Members of {nameof ArrivalStatus}:"
    let names = Array.sort names
    for name in names do
        let status = Enum.Parse(typeof<ArrivalStatus>, name) :?> ArrivalStatus
        printfn $"   {status} ({status:D})"
    // The example displays the following output:
    //       Members of ArrivalStatus:
    //          Early (1)
    //          Late (-1)
    //          OnTime (0)
    //          Unknown (-3)
    
    Dim names() As String = [Enum].GetNames(GetType(ArrivalStatus7))
    Console.WriteLine("Members of {0}:", GetType(ArrivalStatus7).Name)
    Array.Sort(names)
    For Each name In names
        Dim status As ArrivalStatus7 = CType([Enum].Parse(GetType(ArrivalStatus7), name),
                                   ArrivalStatus7)
        Console.WriteLine("   {0} ({0:D})", status)
    Next
    ' The example displays the following output:
    '       Members of ArrivalStatus7:
    '          Early (1)
    '          Late (-1)
    '          OnTime (0)
    '          Unknown (-3)
    
  • Anda dapat memanggil GetValues metode untuk mengambil array yang berisi nilai yang mendasar dalam enumerasi. Selanjutnya, untuk setiap elemen array, Anda dapat memanggil ToObject metode untuk mengonversi bilangan bulat ke nilai enumerasi yang setara. Contoh berikut menggambarkan pendekatan ini.

    var values = Enum.GetValues(typeof(ArrivalStatus));
    Console.WriteLine("Members of {0}:", typeof(ArrivalStatus).Name);
    foreach (ArrivalStatus status in values)
    {
        Console.WriteLine("   {0} ({0:D})", status);
    }
    // The example displays the following output:
    //       Members of ArrivalStatus:
    //          OnTime (0)
    //          Early (1)
    //          Unknown (-3)
    //          Late (-1)
    
    let values = Enum.GetValues typeof<ArrivalStatus>
    printfn $"Members of {nameof ArrivalStatus}:"
    for status in values do
        printfn $"   {status} ({status:D})"
    // The example displays the following output:
    //       Members of ArrivalStatus:
    //          OnTime (0)
    //          Early (1)
    //          Unknown (-3)
    //          Late (-1)
    
    Dim values = [Enum].GetValues(GetType(ArrivalStatus7))
    Console.WriteLine("Members of {0}:", GetType(ArrivalStatus7).Name)
    For Each value In values
        Dim status As ArrivalStatus7 = CType([Enum].ToObject(GetType(ArrivalStatus7), value),
                                         ArrivalStatus7)
        Console.WriteLine("   {0} ({0:D})", status)
    Next
    ' The example displays the following output:
    '       Members of ArrivalStatus7:
    '          OnTime (0)
    '          Early (1)
    '          Unknown (-3)
    '          Late (-1)
    

Anggota non-eksklusif dan atribut Bendera

Salah satu penggunaan umum enumerasi adalah mewakili sekumpulan nilai yang saling eksklusif. Misalnya, ArrivalStatus instans dapat memiliki nilai Early, , OnTimeatau Late. Tidak masuk akal bagi nilai ArrivalStatus instans untuk mencerminkan lebih dari satu konstanta enumerasi.

Namun, dalam kasus lain, nilai objek enumerasi dapat mencakup beberapa anggota enumerasi, dan setiap anggota mewakili bidang bit dalam nilai enumerasi. Atribut FlagsAttribute dapat digunakan untuk menunjukkan bahwa enumerasi terdiri dari bidang bit. Misalnya, enumerasi bernama Pets mungkin digunakan untuk menunjukkan jenis hewan peliharaan di rumah tangga. Ini dapat didefinisikan sebagai berikut.

[Flags]
public enum Pets
{
    None = 0, Dog = 1, Cat = 2, Bird = 4, Rodent = 8,
    Reptile = 16, Other = 32
};
[<Flags>] 
type Pets =
    | None = 0
    | Dog = 1
    | Cat = 2
    | Bird = 4
    | Rodent = 8
    | Reptile = 16
    | Other = 32
<Flags> Public Enum Pets As Integer
   None = 0
   Dog = 1
   Cat = 2
   Bird = 4
   Rodent = 8
   Reptile = 16
   Other = 32
End Enum

Enumerasi Pets kemudian dapat digunakan seperti yang ditunjukkan dalam contoh berikut.

Pets familyPets = Pets.Dog | Pets.Cat;
Console.WriteLine("Pets: {0:G} ({0:D})", familyPets);
// The example displays the following output:
//       Pets: Dog, Cat (3)
let familyPets = Pets.Dog ||| Pets.Cat
printfn $"Pets: {familyPets:G} ({familyPets:D})"
// The example displays the following output:
//       Pets: Dog, Cat (3)
Dim familyPets As Pets = Pets.Dog Or Pets.Cat
Console.WriteLine("Pets: {0:G} ({0:D})", familyPets)
' The example displays the following output:
'       Pets: Dog, Cat (3)

Praktik terbaik berikut harus digunakan saat menentukan enumerasi bitwise dan menerapkan FlagsAttribute atribut .

  • FlagsAttribute Gunakan atribut kustom untuk enumerasi hanya jika operasi bitwise (AND, OR, EXCLUSIVE OR) akan dilakukan pada nilai numerik.

  • Tentukan konstanta enumerasi dalam kekuatan dua, yaitu, 1, 2, 4, 8, dan sebagainya. Ini berarti bendera individu dalam konstanta enumerasi gabungan tidak tumpang tindih.

  • Pertimbangkan untuk membuat konstanta enumerasi untuk kombinasi bendera yang umum digunakan. Misalnya, jika Anda memiliki enumerasi yang digunakan untuk operasi I/O file yang berisi konstanta enumerasi dan Write = 2, pertimbangkan untuk membuat konstanta Read = 1ReadWrite = Read OR Writeenumerasi , yang menggabungkan Read bendera dan Write . Selain itu, operasi bitwise OR yang digunakan untuk menggabungkan bendera mungkin dianggap sebagai konsep lanjutan dalam beberapa keadaan yang seharusnya tidak diperlukan untuk tugas sederhana.

  • Berhati-hatilah jika Anda menentukan angka negatif sebagai konstanta enumerasi bendera karena banyak posisi bendera mungkin diatur ke 1, yang mungkin membuat kode Anda membingungkan dan mendorong kesalahan pengkodean.

  • Cara mudah untuk menguji apakah bendera diatur dalam nilai numerik adalah dengan memanggil metode instans HasFlag , seperti yang ditunjukkan dalam contoh berikut.

    Pets familyPets = Pets.Dog | Pets.Cat;
    if (familyPets.HasFlag(Pets.Dog))
        Console.WriteLine("The family has a dog.");
    // The example displays the following output:
    //       The family has a dog.
    
    let familyPets = Pets.Dog ||| Pets.Cat
    if familyPets.HasFlag Pets.Dog then
        printfn "The family has a dog."
    // The example displays the following output:
    //       The family has a dog.
    
    Dim familyPets As Pets = Pets.Dog Or Pets.Cat
    If familyPets.HasFlag(Pets.Dog) Then
        Console.WriteLine("The family has a dog.")
    End If
    ' The example displays the following output:
    '       The family has a dog.
    

    Setara dengan melakukan operasi BITWISE AND antara nilai numerik dan konstanta enumerasi bendera, yang mengatur semua bit dalam nilai numerik ke nol yang tidak sesuai dengan bendera, lalu menguji apakah hasil operasi tersebut sama dengan konstanta enumerasi bendera. Ini diilustrasikan dalam contoh berikut.

    Pets familyPets = Pets.Dog | Pets.Cat;
    if ((familyPets & Pets.Dog) == Pets.Dog)
        Console.WriteLine("The family has a dog.");
    // The example displays the following output:
    //       The family has a dog.
    
    let familyPets = Pets.Dog ||| Pets.Cat
    if (familyPets &&& Pets.Dog) = Pets.Dog then
        printfn "The family has a dog."
    // The example displays the following output:
    //       The family has a dog.
    
    Dim familyPets As Pets = Pets.Dog Or Pets.Cat
    If familyPets And Pets.Dog = Pets.Dog Then
        Console.WriteLine("The family has a dog.")
    End If
    ' The example displays the following output:
    '       The family has a dog.
    
  • Gunakan None sebagai nama konstanta enumerasi bendera yang nilainya nol. Anda tidak dapat menggunakan None konstanta enumerasi dalam operasi BITWISE AND untuk menguji bendera karena hasilnya selalu nol. Namun, Anda dapat melakukan perbandingan logis, bukan bitwise, antara nilai numerik dan None konstanta enumerasi untuk menentukan apakah bit dalam nilai numerik diatur. Ini diilustrasikan dalam contoh berikut.

    Pets familyPets = Pets.Dog | Pets.Cat;
    if (familyPets == Pets.None)
        Console.WriteLine("The family has no pets.");
    else
        Console.WriteLine("The family has pets.");
    // The example displays the following output:
    //       The family has pets.
    
    let familyPets = Pets.Dog ||| Pets.Cat
    if familyPets = Pets.None then
        printfn "The family has no pets."
    else
        printfn "The family has pets."
    // The example displays the following output:
    //       The family has pets.
    
    Dim familyPets As Pets = Pets.Dog Or Pets.Cat
    If familyPets = Pets.None Then
        Console.WriteLine("The family has no pets.")
    Else
        Console.WriteLine("The family has pets.")
    End If
    ' The example displays the following output:
    '       The family has pets.
    
  • Jangan mendefinisikan nilai enumerasi semata-mata untuk mencerminkan status enumerasi itu sendiri. Misalnya, jangan tentukan konstanta enumerasi yang hanya menandai akhir enumerasi. Jika Anda perlu menentukan nilai terakhir enumerasi, periksa nilai tersebut secara eksplisit. Selain itu, Anda dapat melakukan pemeriksaan rentang untuk konstanta pertama dan terakhir yang dijumlahkan jika semua nilai dalam rentang valid.

Menambahkan metode enumerasi

Karena jenis enumerasi ditentukan oleh struktur bahasa, seperti enum (C#), dan Enum (Visual Basic), Anda tidak dapat menentukan metode kustom untuk jenis enumerasi selain metode yang diwarisi dari Enum kelas. Namun, Anda dapat menggunakan metode ekstensi untuk menambahkan fungsionalitas ke jenis enumerasi tertentu.

Dalam contoh berikut, enumerasi Grades mewakili kemungkinan nilai huruf yang mungkin diterima siswa di kelas. Metode ekstensi bernama Passing ditambahkan ke jenis Grades sehingga setiap instance dari jenis itu sekarang "tahu" apakah itu mewakili nilai kelulusan atau tidak. Kelas ini Extensions juga berisi variabel baca-tulis statis yang menentukan nilai kelulusan minimum. Nilai Passing pengembalian metode ekstensi mencerminkan nilai saat ini dari variabel tersebut.

using System;

// Define an enumeration to represent student grades.
public enum Grades { F = 0, D = 1, C = 2, B = 3, A = 4 };

// Define an extension method for the Grades enumeration.
public static class Extensions
{
    public static Grades minPassing = Grades.D;

    public static bool Passing(this Grades grade)
    {
        return grade >= minPassing;
    }
}

class Example8
{
    static void Main()
    {
        Grades g1 = Grades.D;
        Grades g2 = Grades.F;
        Console.WriteLine("{0} {1} a passing grade.", g1, g1.Passing() ? "is" : "is not");
        Console.WriteLine("{0} {1} a passing grade.", g2, g2.Passing() ? "is" : "is not");

        Extensions.minPassing = Grades.C;
        Console.WriteLine("\nRaising the bar!\n");
        Console.WriteLine("{0} {1} a passing grade.", g1, g1.Passing() ? "is" : "is not");
        Console.WriteLine("{0} {1} a passing grade.", g2, g2.Passing() ? "is" : "is not");
    }
}
// The exmaple displays the following output:
//       D is a passing grade.
//       F is not a passing grade.
//
//       Raising the bar!
//
//       D is not a passing grade.
//       F is not a passing grade.
open System
open System.Runtime.CompilerServices
// Define an enumeration to represent student grades.
type Grades =
    | F = 0
    | D = 1
    | C = 2
    | B = 3
    | A = 4

let mutable minPassing = Grades.D

// Define an extension method for the Grades enumeration.
[<Extension>]
type Extensions =
    [<Extension>]
    static member Passing(grade) = grade >= minPassing

let g1 = Grades.D
let g2 = Grades.F
printfn $"""{g1} {if g1.Passing() then "is" else "is not"} a passing grade."""
printfn $"""{g2} {if g2.Passing() then "is" else "is not"} a passing grade."""

minPassing <- Grades.C
printfn "\nRaising the bar!\n"
printfn $"""{g1} {if g1.Passing() then "is" else "is not"} a passing grade."""
printfn $"""{g2} {if g2.Passing() then "is" else "is not"} a passing grade."""
// The exmaple displays the following output:
//       D is a passing grade.
//       F is not a passing grade.
//
//       Raising the bar!
//
//       D is not a passing grade.
//       F is not a passing grade.
Imports System.Runtime.CompilerServices

' Define an enumeration to represent student grades.
Public Enum Grades As Integer
   F = 0
   D = 1
   C = 2
   B = 3
   A = 4
End Enum   

' Define an extension method for the Grades enumeration.
Public Module Extensions
  Public minPassing As Grades = Grades.D
 
  <Extension>
  Public Function Passing(grade As Grades) As Boolean
     Return grade >= minPassing
  End Function
End Module

Public Module Example
  Public Sub Main()
      Dim g1 As Grades = Grades.D
      Dim g2 As Grades = Grades.F
      Console.WriteLine("{0} {1} a passing grade.", 
                        g1, If(g1.Passing(), "is", "is not"))
      Console.WriteLine("{0} {1} a passing grade.", 
                        g2, If(g2.Passing(), "is", "is not"))
      Console.WriteLine()
      
      Extensions.minPassing = Grades.C
      Console.WriteLine("Raising the bar!")
      Console.WriteLine()
      Console.WriteLine("{0} {1} a passing grade.", 
                        g1, If(g1.Passing(), "is", "is not"))
      Console.WriteLine("{0} {1} a passing grade.", 
                        g2, If(g2.Passing(), "is", "is not"))
  End Sub
End Module
' The exmaple displays the following output:
'       D is a passing grade.
'       F is not a passing grade.
'       
'       Raising the bar!
'       
'       D is not a passing grade.
'       F is not a passing grade.

Contoh

Contoh berikut menunjukkan penggunaan enumerasi untuk mewakili nilai bernama dan enumerasi lain untuk mewakili bidang bit bernama.

using System;

public class EnumTest {
    enum Days { Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday };
    enum BoilingPoints { Celsius = 100, Fahrenheit = 212 };
    [Flags]
    enum Colors { Red = 1, Green = 2, Blue = 4, Yellow = 8 };

    public static void Main() {

        Type weekdays = typeof(Days);
        Type boiling = typeof(BoilingPoints);

        Console.WriteLine("The days of the week, and their corresponding values in the Days Enum are:");

        foreach ( string s in Enum.GetNames(weekdays) )
            Console.WriteLine( "{0,-11}= {1}", s, Enum.Format( weekdays, Enum.Parse(weekdays, s), "d"));

        Console.WriteLine();
        Console.WriteLine("Enums can also be created which have values that represent some meaningful amount.");
        Console.WriteLine("The BoilingPoints Enum defines the following items, and corresponding values:");

        foreach ( string s in Enum.GetNames(boiling) )
            Console.WriteLine( "{0,-11}= {1}", s, Enum.Format(boiling, Enum.Parse(boiling, s), "d"));

        Colors myColors = Colors.Red | Colors.Blue | Colors.Yellow;
        Console.WriteLine();
        Console.WriteLine("myColors holds a combination of colors. Namely: {0}", myColors);
    }
}
open System

type Days =
    | Saturday = 0
    | Sunday = 1
    | Monday = 2
    | Tuesday = 3
    | Wednesday = 4
    | Thursday = 5
    | Friday = 6

type BoilingPoints =
    | Celsius = 100
    | Fahrenheit = 212

[<Flags>]
type Colors =
    | Red = 1
    | Green = 2
    | Blue = 4
    | Yellow = 8

let weekdays = typeof<Days>
let boiling = typeof<BoilingPoints>

printfn "The days of the week, and their corresponding values in the Days Enum are:"

for s in Enum.GetNames weekdays do
    printfn $"""{s,-11}= {Enum.Format(weekdays, Enum.Parse(weekdays, s), "d")}"""

printfn "\nEnums can also be created which have values that represent some meaningful amount."
printfn "The BoilingPoints Enum defines the following items, and corresponding values:"

for s in Enum.GetNames boiling do
    printfn $"""{s,-11}= {Enum.Format(boiling, Enum.Parse(boiling, s), "d")}"""

let myColors = Colors.Red ||| Colors.Blue ||| Colors.Yellow
printfn $"\nmyColors holds a combination of colors. Namely: {myColors}"
Public Class EnumTest
    Enum Days
        Saturday
        Sunday
        Monday
        Tuesday
        Wednesday
        Thursday
        Friday
    End Enum 
    
    Enum BoilingPoints
        Celsius = 100
        Fahrenheit = 212
    End Enum 
    
    <Flags()> _
    Enum Colors
        Red = 1
        Green = 2
        Blue = 4
        Yellow = 8
    End Enum 

    Public Shared Sub Main()
        Dim weekdays As Type = GetType(Days)
        Dim boiling As Type = GetType(BoilingPoints)

        Console.WriteLine("The days of the week, and their corresponding values in the Days Enum are:")

        Dim s As String
        For Each s In  [Enum].GetNames(weekdays)
            Console.WriteLine("{0,-11} = {1}", s, [Enum].Format(weekdays, [Enum].Parse(weekdays, s), "d"))
        
        Next s
        Console.WriteLine()
        Console.WriteLine("Enums can also be created which have values that represent some meaningful amount.")
        Console.WriteLine("The BoilingPoints Enum defines the following items, and corresponding values:")

        For Each s In  [Enum].GetNames(boiling)
            Console.WriteLine("{0,-11} = {1}", s, [Enum].Format(boiling, [Enum].Parse(boiling, s), "d"))
        Next s

        Dim myColors As Colors = Colors.Red Or Colors.Blue Or Colors.Yellow
        Console.WriteLine()
        Console.WriteLine("myColors holds a combination of colors. Namely: {0}", myColors)
    End Sub 
End Class