Sdílet prostřednictvím


Výčty jazyka C#

Návod

Začínáte s vývojem softwaru? Začněte nejprve kurzy Začínáme . Výčty se zobrazí, jakmile potřebujete reprezentovat pevnou sadu voleb v kódu.

Máte zkušenosti v jiném jazyce? Výčty jazyka C# fungují podobně jako výčty v Javě nebo C++ s další podporou bitových příznaků a porovnávání vzorů. Prohlédněte si příznaky a oddíl výrazů přepínače pro vzory specifické pro jazyk C#.

Typ výčtu (nebo enum) definuje sadu pojmenovaných konstant založených na celočíselné hodnotě. Výčty použijte v případě, že hodnota musí být jednou z pevných možností – dnů v týdnu, stavových kódů HTTP, úrovní protokolu nebo pokynů. Výčty umožňují, aby byl kód čitelnější a méně náchylný k chybám než nezpracované celočíselné konstanty, protože kompilátor vynucuje pojmenované hodnoty.

Deklarace výčtu

Definujte výčt s klíčovým slovem enum následovaným názvem typu a jeho členy:

enum Season
{
    Spring,
    Summer,
    Autumn,
    Winter
}

Ve výchozím nastavení je int podkladový typ a hodnoty začínají na 0 a se inkrementují o jeden. Season.Spring je 0, Season.Summer je 1, a tak dále.

Zadání podkladového typu a explicitních hodnot

Můžete zvolit jiný celočíselný typ a přiřadit explicitní hodnoty k řízení číselné reprezentace:

enum HttpStatus : ushort
{
    OK = 200,
    NotFound = 404,
    InternalServerError = 500
}

Explicitní hodnoty použijte, pokud mají čísla externí význam, například stavové kódy HTTP nebo identifikátory protokolu. Základní typ může být jakýkoli celočíselný typ s výjimkou char. Použijte byte, short, ushort, int, uint, long nebo ulong.

Použití výčtů ve výrazech switch

Výčty pracují přirozeně s switch výrazy a porovnávání vzorů. Kompilátor vás upozorní, pokud nezpracujete všechny členy, což pomáhá zabránit chybám při pozdějším přidání nové hodnoty:

static string DescribeSeason(Season season) => season switch
{
    Season.Spring => "Flowers bloom and temperatures rise.",
    Season.Summer => "Long days and warm weather.",
    Season.Autumn => "Leaves change color and fall.",
    Season.Winter => "Short days and cold temperatures.",
    _ => throw new ArgumentOutOfRangeException(nameof(season))
};
var today = Season.Autumn;
Console.WriteLine(DescribeSeason(today));

Vzor zahození_ () zpracovává jakoukoli hodnotu, která není explicitně uvedena. Porovnávání vzorů je funkce jazyka C#, která testuje hodnotu proti obrazci nebo podmínce. V tomto příkladu každý case zkontroluje, jestli výčet odpovídá určitému členu. Výrazy switch patří mezi několik forem porovnávání vzorů. Další informace o porovnávání vzorů naleznete v tématu Porovnávání vzorů.

Bitové příznaky

Pokud výčt představuje kombinaci voleb, nikoli jedinou volbu, definujte každý člen jako mocninu dvou a použijte FlagsAttribute:

[Flags]
enum FileAccess
{
    None = 0,
    Read = 1,
    Write = 2,
    Execute = 4,
    ReadWrite = Read | Write,
    All = Read | Write | Execute
}

Kombinování hodnot pomocí operátoru | a testování jednotlivých příznaků pomocí HasFlag:

var permissions = FileAccess.Read | FileAccess.Write;

Console.WriteLine(permissions);                          // ReadWrite
Console.WriteLine(permissions.HasFlag(FileAccess.Read)); // True
Console.WriteLine(permissions.HasFlag(FileAccess.Execute)); // False

Atribut [Flags] také ovlivňuje ToString(). Zobrazí kombinované hodnoty jako názvy oddělené čárkami (například Read, Write) místo nezpracovaného čísla. Další informace najdete na webu System.FlagsAttribute.

Převod mezi výčty a celými čísly

Explicitní přetypování provádějí mezi výčtovým typem a jeho základním celočíselným typem.

var status = HttpStatus.NotFound;
ushort code = (ushort)status;
Console.WriteLine($"Status: {status} ({code})"); // Status: NotFound (404)

var fromCode = (HttpStatus)200;
Console.WriteLine(fromCode); // OK

Mějte na paměti, že přetypování celého čísla na výčet neověřuje, jestli hodnota odpovídá definovanému členu. Slouží Enum.IsDefined ke kontrole platnosti při přijetí číselného vstupu z externích zdrojů.

Parsování řetězců a iterace hodnot

Základní Enum třída poskytuje metody pro analýzu řetězců a iterování nad všemi definovanými hodnotami:

// Parse a string to an enum value:
var parsed = Enum.Parse<Season>("Winter");
Console.WriteLine(parsed); // Winter

// Try to parse safely. It returns false only when the input can't be parsed. Call Enum.IsDefined to validate named members:
if (Enum.TryParse<Season>("Monsoon", out var unknown))
{
    Console.WriteLine(unknown);
}
else
{
    Console.WriteLine("'Monsoon' is not a valid Season"); // 'Monsoon' is not a valid Season
}

// Iterate over all values in an enum:
foreach (var season in Enum.GetValues<Season>())
{
    Console.WriteLine($"{season} = {(int)season}");
}
// Spring = 0
// Summer = 1
// Autumn = 2
// Winter = 3

Použijte Enum.TryParse<TEnum>(String, Boolean, TEnum) místo Enum.Parse<TEnum>(String), pokud může být vstup neplatný. Místo vyvolání výjimky se vrátí false .

Viz také