Отримайте значення int від enum у C #


1821

У мене є клас під назвою 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)?



11
Я знаю, що я запізнююся на вечірку, але замість того, щоб визначити свій метод, як get(int foo)ви можете його визначити, як get(Question foo)тоді робити кастинг всередині методу, ви можете назвати свій метод якQuestions.Get(Question.Role)
Joe

Відповіді:


2350

Просто киньте перерахунок, напр

int something = (int) Question.Role;

Вищенаведене буде працювати для переважної більшості переліків, які ви бачите в дикій природі, оскільки базовим типом для перерахунків є типовий int.

Однак, як вказує цецифіліпт , перерахунки можуть мати різні основні типи. Якщо перерахування оголошується як uint, longабо ulong, він повинен бути приведений до типу перерахування; наприклад для

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

ви повинні використовувати

long something = (long)StarsInMilkyWay.Wolf424B;

23
@ Харі, це неправда. Ви можете створити перерахунок без кастингу, це не потрібно. і я призначаю номер лише в особливих випадках, більшу частину часу я залишаю його як значення за замовчуванням. але ви можете зробити enum Test { Item = 1 }і побачити, що 1 == (int)Test.Itemце рівно.
Джайдер

33
@Jaider (int)Test.ItemЦе акторський склад ! () - оператор явного передачі.
Sinthia V

48
@Sinthia V він сказав, що ви можете створити його без кастингу, що правильно
Пол Ридвей

7
Якщо базового типу для цього enum Questionне було, intале longцей атрибут урізає Roleцілісне значення!
quaylar

1
Якщо ви приймаєте Enumпараметр, ви знаєте, що ви можете отримати лише фіксовану кількість можливих інтегральних значень. З іншого боку, якщо ви приймаєте просто int, ви повинні перевірити, якщо intце в межах прийнятих значень., Тим самим ускладнюючи код. Ви завжди можете змінювати свої підписи, наприклад, `` public void MyMethod (int x) {// робити щось з x} public void MyMethod (Enum x) {this.MyMethod ((int) x); } `` ``
percebus

307

Так як Перерахування можуть бути будь-яким інтегральним типом ( 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);

Це має працювати незалежно від основного інтегрального типу.


32
Ця методика виявила свою цінність для мене, коли ми маємо справу з загальним типом, де T: enum (насправді T: struct, IConvertible, але це вже інша історія).
aboy021

1
Як би ви змінили це, щоб роздрукувати шістнадцяткове значення сторони? Цей приклад показує десяткове значення. Проблема полягає в тому, що varвона має тип object, тож вам потрібно розблокувати його, і він стане messier ніж я хотів би.
Марк Лаката

2
Я думаю, ви повинні змінити приклад на object val = Convert...etcтой, який varу вашому прикладі завжди буде object.
Меш

2
@TimAbell Все, що я справді можу сказати, - це те, що ми виявили, що динамічно складені сторінки aspx (де вам потрібно розгорнути .cs-файли на реальному сервері) присвоювали цілі числа по-різному кожному значенню. Це означало, що серіалізовані об'єкти - це одна машина, десеріалізуються з різними значеннями на іншій машині і фактично пошкоджуються (викликаючи години плутанини). Ми підняли це разом з MS, і я, мабуть, пригадую, що вони сказали, що автоматично згенеровані цілі числа не гарантуються однаковими при побудові в різних версіях рамки.
NickG

4
@TimAbell Окремим випадком розробник видалив застаріле / невикористане значення Enum, що спричинило виведення всіх інших значень у послідовності. Отже, наші стандарти кодування тепер вимагають, щоб ідентифікатори завжди були чітко вказані, інакше додавання / видалення або навіть автоматичне форматування коду (наприклад, сортування за алфавітом) змінить усі значення, що спричиняють пошкодження даних. Я б настійно радив будь-кому чітко вказати всі цілі числа Enum. Це дуже важливо, якщо вони співвідносяться із значеннями, що зберігаються зовні (у базі даних).
NickG

199

Оголосити його статичним класом, що має публічні константи:

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або все, що ви визначаєте як.


31
Я б використовував, static readonly intтому що константи складаються в їхні жорсткі значення. Дивіться stackoverflow.com/a/755693/492
CAD блокується

96
Це рішення насправді не дає реальної користі сильно набраних переписок. Якщо я хотів лише передати GameState-enum-параметр певному методу, наприклад, компілятор не повинен дозволяти мені передавати будь-яку int-змінну як параметр.
thgc

12
@CADBloke, саме тому ви б використовували, constа не static readonlyтому, що кожного разу при порівнянні static readonlyви здійснюєте виклик методу, щоб отримати значення змінної, тоді як з a constви порівнюєте два типи значень безпосередньо.
blockloop

3
@ brettof86 Так, const був би швидшим, якщо обмеження компіляції ніколи не буде проблемою, то це все добре.
CAD блокується

2
@Zack Я не дуже добре пояснив це, compilation limitationя маю на увазі, що це значення жорстко закодовано, коли ви компілюєте його, тому будь-яке зміна цього значення вимагатиме перекомпіляції всіх збірок, які використовують його. Я схильний погодитися з вами щодо використання, оскільки зміна значень матиме далекосяжні наслідки.
CAD заблокували

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

Це призведе до value == 2.


34
Питання щодо тимчасової змінної непотрібне.
Gishu

1
Тож щось на кшталт цього Question.Get (Convert.ToInt16 (Question.Applications))
jim

6
Ви можете просто кинути в будь-який бік; єдине, на що слід звернути увагу, - це те, що переслідувачі нічого не застосовують (значення перерахунку може бути 288, хоча з цим числом не виникає жодних питань)
Марк Гравелл

@jim: Ні, просто додайте значення: Questions.Get ((int) Question.Applications);
Гуффа

1
@Gishu Можна сказати, що це ... сумнівно. ;)
Фелікс Д.

79

У відповідній примітці, якщо ви хочете отримати 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);

Останні два - просто потворні. Я віддаю перевагу першому.


1
Хоча другий - найшвидший.
Йохан Б

1
Як хтось, хто звик використовувати Mixins у Minecraft, моделювання, другий здається очевидним переможцем.
Соллас

40

Це простіше, ніж ти думаєш - перерахунок - це вже інт. Це просто потрібно нагадати:

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

15
Нітпік: цей перелік вже є цілим . Інші перерахунки можуть бути різного типу - спробуйте "enum SmallEnum: byte {A, B, C}"
mqp

9
Абсолютно вірно. C # посилання: "Кожен тип переліку має базовий тип, який може бути будь-яким інтегральним типом, крім знака".
Майкл Петротта

33

Приклад:

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

І в коді позаду, щоб отримати значення enum:

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

або

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

Енуми збільшаться на 1, і ви можете встановити початкове значення. Якщо ви не встановите початкове значення, воно спочатку буде призначено як 0.


6
Це насправді компілюється?
Пітер Мортенсен

Чи може щось, що є Радж, також бути Рахулом чи Приянка? Ваші цінності суперечать і повинні подвоюватися, щоб бути унікальними, наприклад 0, 1, 2, 4, 8 і т. Д. Це моя основна проблема з перерахунками.
Тимофій Гонсалес

@TimothyGonzalez насправді перераховує просто підрахунок 1, якщо ви чітко не вкажете їх значення;)
derHugo

@derHugo, що залежить, якщо ви вважаєте, що числові значення є базовими 10 або базовими 2.
Тимофій Гонсалес

@TimothyGonzalez добре, що припустити не так вже й багато ... Я лише зазначив, що за замовчуванням вони просто враховуються, 1за intвинятком того, що ви чітко визначаєте інше
derHugo

28

Нещодавно я перейшов від використання перерахунків у своєму коді на користь замість того, щоб використовувати класи із захищеними конструкторами та заздалегідь визначеними статичними екземплярами (завдяки Roelof - C # Забезпечити дійсні значення Enum - метод Futureproof ).

Зважаючи на це, нижче, як я зараз підійшов би до цього питання (включаючи неявне перетворення в / з 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)
}

Перевага такого підходу полягає в тому, що ви отримуєте все, що було б у вас від enum, але ваш код зараз набагато гнучкіший, тому, якщо вам потрібно буде виконувати різні дії на основі значення Question, ви можете вкласти логіку в Questionсебе (тобто в бажаний OO мода), на відміну від розміщення у вашому коді безлічі заяв справи для вирішення кожного сценарію.


NB: Відповідь оновлено 2018-04-27, щоб використовувати функції C # 6; тобто вирази декларації та визначення тіла лямбда-виразів. Перегляньте історію версій для оригінального коду. Це має перевагу зробити дефініцію дещо менш багатослівною; що було однією з головних скарг на підхід цієї відповіді.


2
Я думаю, що це компроміс між явним кастом та кодом, який потрібно написати, щоб його обійти. Все ж люблю, що впровадження просто хочеться, щоб воно було не таким тривалим. +1
Ланкімарт

3
Я використав кілька різних типів класів, структурованих подібним до цього. Я вважаю, що вони творять чудеса, намагаючись дотримуватися методології "не дозволяй мені пізніше бути ідіотом".
Джеймс Хауг

20

Якщо ви хочете отримати ціле число для значення enum, яке зберігається у змінній, для якої буде тип 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.


3
кодування голландською мовою. о Боже.
WiseStrawberry

На жаль, такий підхід дає низьку продуктивність, чим більше ви його використовуєте. Я спробував це в якомусь моєму коді, і з часом мій додаток ставав повільніше і повільніше, з меншим і меншим використанням процесора. Це означало, що нитки чекають на щось - я припускаю, що якесь сміття збирається, можливо, через бокс параметрів enum до ToInt32 (). Переключившись на простий int.Parse (), я зміг повністю усунути цю низьку продуктивність, і продуктивність залишилася такою ж, незалежно від того, як довго діяв код.
Грег

16

Щоб переконатися, що значення перерахунку існує, а потім проаналізувати його, ви також можете зробити наступне.

// 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() + ".");

14

Можливо, я пропустив це, але хтось спробував простий загальний метод розширення?

Це чудово працює для мене. Таким чином, ви можете уникнути передачі типів у своєму API, але в кінцевому підсумку це призведе до операції зміни типу. Це хороший випадок для програмування Roslyn, щоб компілятор створив метод GetValue <T>.

    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;
    }
}

Можливо, тому, що виконуючи (int) customFlag менше друкуючи все навколо і роблячи більш-менш те саме?
Тім Кітінг

Re "Можливо, я пропустив це, але хтось спробував простий загальний метод розширення ?" : SixOThree сказав " Замість цього використовувати метод розширення ", а Бронек сказав: "Це можна зробити, застосувавши метод розширення до визначеного типу enum" .
Пітер Мортенсен

13

Ще один спосіб зробити це:

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

Це призведе до:

Name: Role, Value: 2

12
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, який задовольняє такий тип очікування у багатьох областях.


11
int number = Question.Role.GetHashCode();

numberповинні мати значення 2.


GetHashCode - це один із способів отримати значення від загальної маски Enum
ThanhLD

Зверніть увагу , що це тільки «законним» для bool*, byte, ushort, int, і uint**. GetHashCode для інших типів змінює значення, наприклад, робить деякі бітчіфти та xors. (* 1/0, **, переданий до int звичайно). Але загалом просто не робіть цього, якщо це не ваш власний приватний код.
AnorZaken

10

Це можна зробити, застосувавши метод розширення до визначеного типу enum:

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

Це спрощує отримання int значення поточного значення enum:

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

або

int value = Question.Role.getNumberValue();

5
Бронек, те, що ви зробили, - це складати неінформативний синтаксис через метод (не загальний btw) розширення, який насправді вимагає більше часу для запису. Я не бачу, як це краще, ніж оригінальне рішення Tetraneutron. Давайте не будемо робити це в чаті, допомога завжди вітається в stackoverflow, і всі тут допоможуть. Будь ласка, сприймайте мій коментар як конструктивну критику.
Бенджамін Грюнбаум

2
Перш за все, Бенджамін, чому ти видалив мій коментар? Я не розумію твоїх рішень - можливо, хтось інший через громаду погодиться з моїм коментарем. По-друге, моє рішення обгортає одне з тетраутронів і точно так простіше і менше писати, оскільки метод розширення запропонований IntelliSense.Так я вважаю, що ваше рішення не є неупередженим та репрезентативним. Я бачу багато подібних відповідей на Stack, і це нормально. Я завжди використовую своє рішення, і, можливо, є кілька людей, які вибрали б моє рішення в майбутньому, але ці негативні моменти ускладнюють пошук. Більшість з них правильно і не копіюється.
Бронек

3
@Bronek Якщо ти мене не пінгуєш, я не вказую, що ти відповів. Я не видалив ваш коментар, я не маю можливості або хочу це зробити. Можливо, мод прийшов і видалив його - ви можете позначити його на увазі модератора і запитати, чому ще краще, - запитайте в Meta Stack Overflow . У мене є думка щодо вашого рішення з точки зору програмування, що цілком праворуч - ось з чого слід почати коментарі, не потрібно сприймати це особисто.
Бенджамін Груенбаум

8

Замість цього використовуйте метод розширення:

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

А використання трохи красивіше:

var intValue = Question.Role.IntValue();

7
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 a 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);
}

костюм - "10. (карткові ігри) Кожен із наборів пачок карт відрізняється кольором та / або певними емблемами, такими як лопати, серця, алмази або клуби традиційних англо-іспаномовних та французьких гральних карт".
Пітер Мортенсен

Пояснення зразкового коду було б в порядку ( відредагувавши свою відповідь , а не тут у коментарях).
Пітер Мортенсен

нуль, як правило, зарезервовано для невстановленого / непознаного стану в перерахунках, незвично його визначати так
Чад Грант

6

Використання:

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

Це призведе до value == 2.

Це справедливо лише в тому випадку, якщо перерахунок поміщається всередину int.


1
Це справедливо лише в тому випадку, якщо перерахунок поміщається всередину intкурсу, оскільки GetHashCodeповертає ціле число.
РБ.

5

Оскільки переліки можуть бути оголошені з декількома примітивними типами, може бути корисним загальний метод розширення для передачі будь-якого типу enum.

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;

4

Далі йде метод розширення

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;
}

4

Мій улюблений хак з 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

Відмова:

Це не працює для перерахунків на основі довгого.


3

Найпростішим рішенням, про який я можу придумати, є перевантаження такого Get(int)методу:

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

де [modifiers]зазвичай може бути те саме, що і для Get(int)методу. Якщо ви не можете редагувати Questionsклас або чомусь не хочете, ви можете перевантажити метод, написавши розширення:

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

3

Приклад, який я хотів би запропонувати "отримати значення" int "від enum", є

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

int answer = (int)Sample.Book;

Тепер відповідь буде 1.



2

Спробуйте це замість перетворення enum в int:

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

2

У Visual Basic це повинно бути:

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

Private value As Integer = CInt(Question.Role)

3
Питання до C #.
Ctrl S

2
У заголовку написано "Отримати значення int з enum в C #" .
Пітер Мортенсен

0

Я придумав цей метод розширення, який включає поточні особливості мови. Використовуючи динамічний, мені не потрібно робити це загальним методом і вказувати тип, який забезпечує виклик більш простим і послідовним:

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;
    }

будь ласка, ні, ви можете зробити це все в одному рядку Convert.Changetype (e, e.GetTypeCode ()) і отримати об'єкт назад, не потрібно динаміки чи методу розширення
Чад Грант

Я не погоджуюся з використанням Convert. Просто використовувати акторський склад буде простіше. Моя мета полягала в тому, щоб можна було перетворити будь-яку перерахунок на її значення, не використовуючи кастинг. Це дозволяє змінювати тип перерахунку без необхідності зміни всіх пов'язаних ролей - але коли це станеться ?. Метод розширення працює правильно. Однак у мене виникає проблема з цим, оскільки він динамічний, компілятор не може перевірити тип (як видається, для всього оператора), що означає перевірку типу при запуску - не гарне рішення. Я думаю, я повернусь на касти.
Джефф

1
Я не говорив, що використовувати його над кастом, лише те, що цей код є безглуздим і нічого не виконує, насправді робить проблему ще гіршою. Я рекомендую видалити це рішення
Чад Грант
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.