Вопрос

У меня есть класс под названием Questions (множественное число).В этом классе есть перечисление под названием Question (единственное число), которое выглядит так.

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

в Questions класс, у меня есть get(int foo) функция, которая возвращает Questions возражать против этого foo.Есть ли простой способ получить целочисленное значение из перечисления, чтобы я мог сделать что-то вроде Questions.Get(Question.Role)?

Это было полезно?

Решение

Просто введите перечисление, например.

int something = (int) Question.Role;

Вышеупомянутое будет работать для подавляющего большинства перечислений, которые вы видите в дикой природе, поскольку базовым типом по умолчанию для перечисления является int.

Однако, как Сесилфиллип указывает, что перечисления могут иметь разные базовые типы.Если перечисление объявлено как uint, long, или ulong, его следует привести к типу перечисления;напримердля

enum StarsInMilkyWay:long {Sun = 1, V645Centauri = 2 .. Wolf424B = 2147483649};

тебе следует использовать

long something = (long)StarsInMilkyWay.Wolf424B;

Другие советы

Поскольку Enums может быть любого целочисленного типа (byte, int, short, и т. д.), более надежный способ получить базовое целочисленное значение перечисления — использовать метод GetTypeCode метод в сочетании с Convert сорт:

enum Sides {
    Left, Right, Top, Bottom
}
Sides side = Sides.Bottom;

object val = Convert.ChangeType(side, side.GetTypeCode());
Console.WriteLine(val);

Это должно работать независимо от базового целочисленного типа.

Объявите его как статический класс, имеющий общедоступные константы:

public static class Question
{
    public const int Role = 2;
    public const int ProjectFunding = 3;
    public const int TotalEmployee = 4;
    public const int NumberOfServers = 5;
    public const int TopBusinessConcern = 6;
}

И тогда вы можете ссылаться на него как Question.Role, и он всегда оценивается как int или как вы это определяете.

Question question = Question.Role;
int value = (int) question;

приведет к value == 2.

Кстати, если вы хотите получить int значение от System.Enum, затем учитывая e здесь:

Enum e = Question.Role;

Вы можете использовать:

int i = Convert.ToInt32(e);
int i = (int)(object)e;
int i = (int)Enum.Parse(e.GetType(), e.ToString());
int i = (int)Enum.ToObject(e.GetType(), e);

Последние два просто ужасны.Я предпочитаю первый.

Это проще, чем вы думаете: перечисление уже является int.Просто нужно напомнить:

int y = (int)Question.Role;
Console.WriteLine(y); // prints 2

Пример:

public Enum EmpNo
{
    Raj = 1,
    Rahul,
    Priyanka
}

И в коде, чтобы получить значение перечисления:

int setempNo = (int)EmpNo.Raj; //This will give setempNo = 1

или

int setempNo = (int)EmpNo.Rahul; //This will give setempNo = 2

Перечисления будут увеличиваться на 1, и вы сможете установить начальное значение.Если вы не установите начальное значение, изначально ему будет присвоено значение 0.

Недавно я отказался от использования перечислений в своем коде в пользу использования классов с защищенными конструкторами и предопределенными статическими экземплярами (спасибо Roelof — C# Обеспечение допустимых значений перечислений — метод, ориентированный на будущее).

В свете этого ниже показано, как я сейчас подхожу к этой проблеме (включая неявное преобразование в/из int).

public class Question
{
    // Attributes
    protected int index;
    protected string name;
    // Go with a dictionary to enforce unique index
    //protected static readonly ICollection<Question> values = new Collection<Question>();
    protected static readonly IDictionary<int,Question> values = new Dictionary<int,Question>();

    // Define the "enum" values
    public static readonly Question Role = new Question(2,"Role");
    public static readonly Question ProjectFunding = new Question(3, "Project Funding");
    public static readonly Question TotalEmployee = new Question(4, "Total Employee");
    public static readonly Question NumberOfServers = new Question(5, "Number of Servers");
    public static readonly Question TopBusinessConcern = new Question(6, "Top Business Concern");

    // Constructors
    protected Question(int index, string name)
    {
        this.index = index;
        this.name = name;
        values.Add(index, this);
    }

    // Easy int conversion
    public static implicit operator int(Question question) =>
        question.index; //nb: if question is null this will return a null pointer exception

    public static implicit operator Question(int index) =>        
        values.TryGetValue(index, out var question) ? question : null;

    // Easy string conversion (also update ToString for the same effect)
    public override string ToString() =>
        this.name;

    public static implicit operator string(Question question) =>
        question?.ToString();

    public static implicit operator Question(string name) =>
        name == null ? null : values.Values.FirstOrDefault(item => name.Equals(item.name, StringComparison.CurrentCultureIgnoreCase));


    // If you specifically want a Get(int x) function (though not required given the implicit converstion)
    public Question Get(int foo) =>
        foo; //(implicit conversion will take care of the conversion for you)
}

Преимущество этого подхода в том, что вы получаете все, что могли бы получить из перечисления, но ваш код теперь намного более гибок, поэтому вам нужно будет выполнять различные действия в зависимости от значения Question, вы можете вложить логику в Question сам (т.в предпочтительном объектно-ориентированном стиле), а не размещать в коде множество операторов Case для решения каждого сценария.


Примечание:Ответ обновлен 27 апреля 2018 г. для использования функций C# 6;то естьвыражения объявлений и определения тела лямбда-выражений.Видеть лист регистраций изменений для исходного кода.Преимущество этого заключается в том, что определение становится немного менее многословным;что было одной из основных жалоб на подход этого ответа.

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

enum Talen
{
    Engels = 1, Italiaans = 2, Portugees = 3, Nederlands = 4, Duits = 5, Dens = 6
}

Talen Geselecteerd;    

public void Form1()
{
    InitializeComponent()
    Geselecteerd = Talen.Nederlands;
}

// You can use the Enum type as a parameter, so any enumeration from any enumerator can be used as parameter
void VeranderenTitel(Enum e)
{
    this.Text = Convert.ToInt32(e).ToString();
}

Это изменит заголовок окна на 4, поскольку переменная Geselecteerd является Talen.Nederlands.Если я изменю его на Talen.Portugees и снова вызовем метод, текст изменится на 3.

Мне было трудно найти это простое решение в Интернете, и я не смог его найти, поэтому я что-то тестировал и обнаружил это.Надеюсь это поможет.;)

Чтобы убедиться, что значение перечисления существует, а затем проанализировать его, вы также можете сделать следующее.

// Fake Day of Week
string strDOWFake = "SuperDay";
// Real Day of Week
string strDOWReal = "Friday";
// Will hold which ever is the real DOW.
DayOfWeek enmDOW;

// See if fake DOW is defined in the DayOfWeek enumeration.
if (Enum.IsDefined(typeof(DayOfWeek), strDOWFake))
{
// This will never be reached since "SuperDay" 
// doesn't exist in the DayOfWeek enumeration.
    enmDOW = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), strDOWFake);
}
// See if real DOW is defined in the DayOfWeek enumeration.
else if (Enum.IsDefined(typeof(DayOfWeek), strDOWReal))
{
    // This will parse the string into it's corresponding DOW enum object.
    enmDOW = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), strDOWReal);
}

// Can now use the DOW enum object.
Console.Write("Today is " + enmDOW.ToString() + ".");

Надеюсь, это поможет.

Возможно, я это пропустил, но пробовал ли кто-нибудь простой универсальный метод расширения.Это отлично работает для меня.Таким образом вы можете избежать приведения типов в своем API, но в конечном итоге это приведет к операции изменения типа.Это хороший случай для программирования Roselyn так, чтобы компилятор создавал для вас метод GetValue.

    public static void Main()
    {
        int test = MyCSharpWrapperMethod(TestEnum.Test1);

        Debug.Assert(test == 1);
    }

    public static int MyCSharpWrapperMethod(TestEnum customFlag)
    {
        return MyCPlusPlusMethod(customFlag.GetValue<int>());
    }

    public static int MyCPlusPlusMethod(int customFlag)
    {
        //Pretend you made a PInvoke or COM+ call to C++ method that require an integer
        return customFlag;
    }

    public enum TestEnum
    {
        Test1 = 1,
        Test2 = 2,
        Test3 = 3
    }
}

public static class EnumExtensions
{
    public static T GetValue<T>(this Enum enumeration)
    {
        T result = default(T);

        try
        {
            result = (T)Convert.ChangeType(enumeration, typeof(T));
        }
        catch (Exception ex)
        {
            Debug.Assert(false);
            Debug.WriteLine(ex);
        }

        return result;
    }
}    

Еще один способ сделать это:

Console.WriteLine("Name: {0}, Value: {0:D}", Question.Role);

Результат:

Name: Role, Value: 2
public enum QuestionType
{
    Role = 2,
    ProjectFunding = 3,
    TotalEmployee = 4,
    NumberOfServers = 5,
    TopBusinessConcern = 6
}

...прекрасное заявление.

Вам нужно привести результат к int следующим образом:

int Question = (int)QuestionType.Role

В противном случае тип по-прежнему QuestionType.

Этот уровень строгости соответствует стандарту C#.

Одной из альтернатив является использование вместо этого объявления класса:

public class QuestionType
{
    public static int Role = 2,
    public static int ProjectFunding = 3,
    public static int TotalEmployee = 4,
    public static int NumberOfServers = 5,
    public static int TopBusinessConcern = 6
}

Декларировать это менее элегантно, но вам не нужно приводить это в код:

int Question = QuestionType.Role

Альтернативно, вы можете чувствовать себя более комфортно с Visual Basic, который удовлетворяет подобные ожидания во многих областях.

Вы можете сделать это, реализовав Метод расширения к вашему определенному типу перечисления:

public static class MyExtensions
{
    public static int getNumberValue(this Question questionThis)
    {
        return (int)questionThis;
    }
}

Это упрощает получение значения int текущего значения перечисления:

Question question = Question.Role;
int value = question.getNumberValue();

или

int value = Question.Role.getNumberValue();
int number = Question.Role.GetHashCode();

number должно иметь значение 2.

Как насчет метода расширения:

public static class ExtensionMethods
{
    public static int IntValue(this Enum argEnum)
    {
        return Convert.ToInt32(argEnum);
    }
}

И использование немного красивее:

var intValue = Question.Role.IntValue();
public enum Suit : int
{
    Spades = 0,
    Hearts = 1,
    Clubs = 2,
    Diamonds = 3
}

Console.WriteLine((int)(Suit)Enum.Parse(typeof(Suit), "Clubs"));

//from int
Console.WriteLine((Suit)1);

//From number you can also
Console.WriteLine((Suit)Enum.ToObject(typeof(Suit), 1));

if (typeof(Suit).IsEnumDefined("Spades"))
{
    var res = (int)(Suit)Enum.Parse(typeof(Suit), "Spades");
    Console.Out.WriteLine("{0}", res);
}

Мой любимый хак с int или меньшими перечислениями:

GetHashCode();

Для перечисления

public enum Test
{
    Min = Int32.MinValue,
    One = 1,
    Max = Int32.MaxValue,
}

этот

var values = Enum.GetValues(typeof(Test));

foreach (var val in values) 
{
    Console.WriteLine(val.GetHashCode());
    Console.WriteLine(((int)val));
    Console.WriteLine(val);
}

результаты

one
1
1  
max
2147483647
2147483647    
min
-2147483648
-2147483648    

Отказ от ответственности:Не работает для перечислений, основанных на длинных

Ниже приведен метод расширения

public static string ToEnumString<TEnum>(this int enumValue)
{
    var enumString = enumValue.ToString();
    if (Enum.IsDefined(typeof(TEnum), enumValue))
    {
        enumString = ((TEnum) Enum.ToObject(typeof (TEnum), enumValue)).ToString();
    }
    return enumString;
}

Поскольку перечисления могут быть объявлены с использованием нескольких примитивных типов, может оказаться полезным универсальный метод расширения для приведения любого типа перечисления.

enum Box
{
    HEIGHT,
    WIDTH,
    DEPTH
}

public static void UseEnum()
{
    int height = Box.HEIGHT.GetEnumValue<int>();
    int width = Box.WIDTH.GetEnumValue<int>();
    int depth = Box.DEPTH.GetEnumValue<int>();
}

public static T GetEnumValue<T>(this object e) => (T)e;

Пример, который я хотел бы предложить, «получить значение int из перечисления»:

public enum Sample
{Book =1, Pen=2, Pencil =3}

int answer = (int)Sample.Book;

теперь ответ будет 1.

Я надеюсь, что это может помочь кому-то.

Самое простое решение, которое я могу придумать, - это перегрузить Get(int) такой метод:

[modifiers] Questions Get(Question q)
{
    return Get((int)q);
}

где [modifiers] обычно может быть таким же, как для Get(int) метод.Если вы не можете редактировать Questions class или по каким-то причинам не хотите. Вы можете перегрузить метод, написав расширение:

public static class Extensions
{
    public static Questions Get(this Questions qs, Question q)
    {
        return qs.Get((int)q);
    }
}

Попробуйте это вместо преобразования перечисления в int:

public static class ReturnType
{
    public static readonly int Success = 1;
    public static readonly int Duplicate = 2;
    public static readonly int Error = -1;        
}

В Вб.Должен быть

Public Enum Question
    Role = 2
    ProjectFunding = 3
    TotalEmployee = 4
    NumberOfServers = 5
    TopBusinessConcern = 6
End Enum

Private value As Integer = CInt(Question.Role)

Я немного опоздал, но придумал этот метод расширения, включающий текущие функции языка.Используя динамический метод, мне не нужно делать его универсальным методом и указывать тип, который делает вызов более простым и последовательным.Пожалуйста, дайте мне знать, если я сделал что-то не так:

public static class EnumEx
{
    public static dynamic Value(this Enum e)
    {
        switch (e.GetTypeCode())
        {
        case TypeCode.Byte:
            {
                return (byte) (IConvertible) e;
            }
        case TypeCode.Int16:
            {
                return (short) (IConvertible) e;
            }
        case TypeCode.Int32:
            {
                return (int) (IConvertible) e;
            }
        case TypeCode.Int64:
            {
                return (long) (IConvertible) e;
            }
        case TypeCode.UInt16:
            {
                return (ushort) (IConvertible) e;
            }
        case TypeCode.UInt32:
            {
                return (uint) (IConvertible) e;
            }
        case TypeCode.UInt64:
            {
                return (ulong) (IConvertible) e;
            }
        case TypeCode.SByte:
            {
                return (sbyte) (IConvertible) e;
            }
        }

        return 0;
    }
Question question = Question.Role;
int value = question.GetHashCode();

приведет к value == 2.

Это верно только в том случае, если перечисление помещается внутри int

Попробуй это :

int value = YourEnum.ToString("D");
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top