НейроАгент

Как получить целочисленное значение из перечисления в C#

Узнайте, как извлекать целочисленные значения из перечислений C# с помощью приведения типов и Convert.ToInt32(). Полное руководство с примерами для реализации метода Questions.Get().

Вопрос

Как получить целочисленное значение из enum в C#?

У меня есть класс Questions (во множественном числе), который содержит enum с названием Question (в единственном числе), определенный следующим образом:

csharp
public enum Question
{
    Role = 2,
    ProjectFunding = 3,
    TotalEmployee = 4,
    NumberOfServers = 5,
    TopBusinessConcern = 6
}

В классе Questions есть метод get(int foo), который возвращает объект Questions для указанного целочисленного значения. Я ищу способ извлечь целочисленное значение из enum, чтобы вызывать метод следующим образом: Questions.Get(Question.Role).

Как можно извлечь базовое целочисленное значение из enum в C# для использования в вызовах методов?

НейроАгент

Чтобы получить целочисленное значение из перечисления C#, можно использовать явное приведение с помощью (int)Question.Role или метод Convert.ToInt32(). В вашем конкретном случае приведение члена перечисления непосредственно к целому числу вернет его базовое значение, что позволит вызвать Questions.Get((int)Question.Role) для получения значения 2 для члена перечисления Role.


Содержание


Понимание преобразования перечисления в целое число

В C# перечисления (enum) - это типы значений, которые представляют набор именованных констант. Каждый член перечисления имеет базовое значение, которое по умолчанию является целым числом. Когда вы определяете перечисление, такое как ваше Question:

csharp
public enum Question
{
    Role = 2,
    ProjectFunding = 3,
    TotalEmployee = 4,
    NumberOfServers = 5,
    TopBusinessConcern = 6
}

Каждый член связан с определенным целочисленным значением. Базовый тип перечисления определяет, какие значения оно может хранить - хотя int является типом по умолчанию, перечисления также могут использовать byte, sbyte, short, ushort, uint, long или ulong в качестве базового типа.


Базовые методы преобразования

Существует несколько способов преобразования перечисления в его базовое целочисленное значение в C#:

1. Явное приведение

Самый прямой метод - использование явного приведения:

csharp
int roleValue = (int)Question.Role;        // Возвращает 2
int fundingValue = (int)Question.ProjectFunding;  // Возвращает 3

2. Метод Convert.ToInt32()

Метод Convert.ToInt32() предоставляет более явный подход:

csharp
int roleValue = Convert.ToInt32(Question.Role);     // Возвращает 2

3. Enum.GetUnderlyingType()

Вы также можете проверить базовый тип вашего перечисления:

csharp
Type underlyingType = Enum.GetUnderlyingType(typeof(Question));
Console.WriteLine(underlyingType);  // System.Int32

4. Обобщенный метод преобразования

Для более повторно используемого подхода вы можете создать метод расширения:

csharp
public static class EnumExtensions
{
    public static int ToInt<T>(this T enumValue) where T : struct, Enum
    {
        return Convert.ToInt32(enumValue);
    }
}

// Использование:
int value = Question.Role.ToInt();

Реализация метода Questions.Get

На основе вашего описания вам нужен метод, который принимает целочисленный параметр и возвращает объект Questions. Вот как это можно реализовать:

Реализация метода

csharp
public class Questions
{
    private readonly Dictionary<int, Question> _questionMap;
    
    public Questions()
    {
        // Инициализация сопоставления целочисленных значений с членами перечисления
        _questionMap = new Dictionary<int, Question>
        {
            { 2, Question.Role },
            { 3, Question.ProjectFunding },
            { 4, Question.TotalEmployee },
            { 5, Question.NumberOfServers },
            { 6, Question.TopBusinessConcern }
        };
    }
    
    public Questions Get(int foo)
    {
        // Реализация зависит от того, что представляет объект Questions
        // Это базовый пример - адаптируйте под свои нужды
        return new Questions();
    }
    
    public static Questions GetByEnum(Question question)
    {
        // Метод, который принимает перечисление и преобразует в int перед вызовом Get
        return Get((int)question);
    }
    
    // Использование:
    // Questions.Get(Question.Role);        // Прямое использование перечисления
    // Questions.Get((int)Question.Role);  // Явное приведение
}

Альтернативная реализация с параметром перечисления

Если вы хотите сохранить сигнатуру метода, принимающего целое число, но также поддерживать использование перечисления, вы можете создать перегрузку:

csharp
public class Questions
{
    public Questions Get(int foo)
    {
        // Ваша реализация
        return this;
    }
    
    public Questions Get(Question question)
    {
        return Get((int)question);
    }
    
    // Использование:
    var questions1 = Questions.Get(2);                    // Использование целого числа
    var questions2 = Questions.Get(Question.Role);       // Использование перечисления
}

Практические примеры и варианты использования

Пример 1: Работа со значениями перечисления

csharp
// Получение отдельных значений перечисления в виде целых чисел
int roleValue = (int)Question.Role;
int fundingValue = Convert.ToInt32(Question.ProjectFunding);

// Использование в вычислениях
int totalValue = roleValue + fundingValue;  // 2 + 3 = 5

// Сравнение с целочисленными значениями
if (Question.Role == (Question)2)
{
    Console.WriteLine("Role имеет значение 2");
}

Пример 2: Преобразование перечисления в словарь

csharp
// Создание словаря, сопоставляющего имена перечисления со значениями
var enumValues = Enum.GetValues(typeof(Question));
var enumDictionary = new Dictionary<string, int>();

foreach (Question value in enumValues)
{
    enumDictionary[value.ToString()] = (int)value;
}

// Результат:
// enumDictionary["Role"] = 2
// enumDictionary["ProjectFunding"] = 3
// и т.д.

Пример 3: Валидация перечисления

csharp
public bool IsValidQuestionValue(int value)
{
    return Enum.IsDefined(typeof(Question), value);
}

// Использование:
Console.WriteLine(IsValidQuestionValue(2));   // true
Console.WriteLine(IsValidQuestionValue(99));  // false

Распространенные ошибки и лучшие практики

Распространенные проблемы, которых следует избегать

  1. Исключения недопустимого приведения: Будьте осторожны при приведении целых чисел к перечислениям без валидации:
csharp
int invalidValue = 99;
Question question = (Question)invalidValue;  // Это скомпилируется, но может вызвать проблемы
  1. Несоответствия базовых типов: Помните, что перечисления могут иметь разные базовые типы:
csharp
public enum SmallByte : byte
{
    Value1 = 200,
    Value2 = 250
}

// Это сработает:
byte smallByte = (byte)SmallByte.Value1;

// Но это может вызвать переполнение:
int largeInt = SmallByte.Value1;  // Неявное преобразование в int

Лучшие практики

  1. Используйте Enum.IsDefined() для валидации:
csharp
public void ProcessQuestion(int questionValue)
{
    if (!Enum.IsDefined(typeof(Question), questionValue))
    {
        throw new ArgumentException($"Недопустимое значение вопроса: {questionValue}");
    }
    
    // Безопасно продолжать
    Questions.Get(questionValue);
}
  1. Рассмотрите использование Enum.GetValues() для динамических операций:
csharp
var allQuestions = Enum.GetValues(typeof(Question));
foreach (Question question in allQuestions)
{
    int value = (int)question;
    Console.WriteLine($"{question} = {value}");
}
  1. Для C# 7.0+ используйте сопоставление с шаблоном:
csharp
switch (questionValue)
{
    case (int)Question.Role:
        // Обработка Role
        break;
    case (int)Question.ProjectFunding:
        // Обработка ProjectFunding
        break;
    default:
        throw new ArgumentOutOfRangeException(nameof(questionValue));
}
  1. Рассмотрите использование методов расширения для перечисления для повторного использования:
csharp
public static class EnumExtensions
{
    public static int GetValue<T>(this T enumValue) where T : Enum
    {
        return Convert.ToInt32(enumValue);
    }
}

// Использование:
int value = Question.Role.GetValue();

Заключение

Чтобы получить целочисленное значение из перечисления C#, используйте явное приведение (int)enumValue или Convert.ToInt32(enumValue). Для вашего конкретного сценария Questions.Get(Question.Role) вы можете реализовать перегрузки методов или преобразовать перечисление в целое число перед вызовом метода. Всегда валидируйте значения перечисления, чтобы избежать недопустимых приведений, и рассмотрите использование методов расширения для более чистого и повторно используемого кода. Ключевое понимание заключается в том, что перечисления по сути являются именованными целочисленными константами с преимуществами строгой типизации.


Источники

  1. Microsoft Docs - Тип перечисления (справочник по C#)
  2. Microsoft Docs - Как преобразовывать между типами перечисления и целыми числами
  3. Microsoft Docs - Метод Enum.GetUnderlyingType
  4. Microsoft Docs - Метод Convert.ToInt32