Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
titan4ik
119 / 97 / 19
Регистрация: 08.01.2017
Сообщений: 577
1

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

01.11.2017, 16:44. Просмотров 296. Ответов 2
Метки нет (Все метки)

Поскольку прямая лобовая передача типа перечисления в метод в качестве параметра невозможна (?), то сделал два (может быть и третий) варианта как эту проблему решить (вроде всё работает).
Второй вариант ещё хуже первого)
Прошу прокомментировать и м.б. предложить что-то лучше.
Нужно иметь ввиду, что часто, когда пишут про передачу перечисления в метод, то на самом деле передают экземпляр конкретного типа перечисления. И так и описывают метод - для конкретного типа перечисления (по поиску попались только такие примеры). То есть формальный параметр имеет тип конкретного перечисления. А тут задача, что есть несколько конкретных типов перечислений. А метод нужно описать и использовать для них всех один.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//задача - обойти проблему невозможности прямой передачи в метод типа перечисления как параметра
    //то есть, невозможно прямо передать в метод En1, En2 или En3 в качестве параметра
    class Program
    {
        //объявление и сразу инициализация (а как иначе?) трёх типов перечислений
        public enum En1 { RepeatInput, Aaa1, Bbb1, Ccc1, Ddd1 }
        public enum En2 { RepeatInput, Aaa2 = 10, Bbb2, Ccc2 }
        public enum En3 { RepeatInput, Aaa3, Bbb3, Ccc3, Ddd3, Ggg3 }
        static void Main()
        {
            //ввод входных данных программы (имитируем инициализацией переменных в коде), которые могут принимать 
            ///только значения перечислителей из списка инициализации соотв-х перечислений
           
            int value1 = 1;
            int value2 = 2;
            int value3 = 4;
 
            //объявление экземпляров перечислений соотв-х типов и инициализация их 
            //перечеслителем (константой из списка перечислителя) с именем RepeatInput со значением = 0
            //такое значение параметра будет говорить об ошибке ввода
            En1 paramEn1 = En1.RepeatInput;
            En2 paramEn2 = En2.RepeatInput;
            En3 paramEn3 = En3.RepeatInput;
 
            //проверка соответствия входных данных их возможным значениям (перечислениям) и просвоение в случае успеха
            //для этого передаём экземпляр перечисления в качестве параметра метода, 
            //а уже в методе получаем тип перечисления соотв-ий данному экземпляру для вызова метода Enum.GetValues()
            EnumChoice(paramEn1, value1);
            EnumChoice(paramEn2, value2);
            EnumChoice(paramEn3, value3);
            Console.WriteLine();
 
            //ВТОРОЙ ВАРИАНТ - ничем не лучше, требует доп сущностей и избыточность параметров метода
            //Получаем сначала типы типов перечислений как объекты типа Type, потом передаём их в методы как параметры типа Type
            Type t1 = typeof(En1);
            Type t2 = typeof(En2);
            Type t3 = typeof(En3);
            ////или так
            //Type t1 = paramEn1.GetType();
            //Type t2 = paramEn2.GetType();
            //Type t3 = paramEn3.GetType();
 
            EnumChoice(t1, paramEn1, value1);
            EnumChoice(t2, paramEn2, value2);
            EnumChoice(t3, paramEn3, value3);
            Console.ReadLine();
 
            //ТРЕТИЙ ВАРИАНТ - наверное можно модернизировать второй вариант 
            //и обойтись в методе двумя параметрами 
            //static public void EnumChoice(Type t, int value)
            //а экземпляр типа переданногов  мтеод  через объект t найти в программе с пом рефлексии (а если он не один...). 
            //Но это уже слишком великомудро и м.б опасно.
        }
 
        //Вариант первый метода. Передаём экземпляр перечисления в качестве параметра метода, 
        //а уже в методе получаем тип перечисления соотв-ий данному экземпляру
 
        static public void EnumChoice( Enum paramEn, int value)
        {
            
            foreach (var u1 in Enum.GetValues(paramEn.GetType()))
                //кстати, не понятно почему нельзя было определить метод класса Enum как-то проще, 
                //чтобы работало это - "Enum.GetValues(EnN)" , где EnN - конкретный тип перечисления
            {
                if ((int)u1 == value)
                    paramEn = (Enum)u1;               
            }
            Console.WriteLine(paramEn);              
        }
 
        //Второй вариант метода, перегрузка то бишь
        //сначала получаем тип типа перечисления, а потом передаём его в метод как параметр
 
        static public void EnumChoice(Type t, Enum paramEn, int value)
        {
            foreach (var u1 in Enum.GetValues(t))           
            {
                if ((int)u1 == value)
                    paramEn = (Enum)u1;                
            }
            Console.WriteLine(paramEn);
        }
    }
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.11.2017, 16:44
Ответы с готовыми решениями:

Метод, определяющий все символы, встречающиеся в переданной в качестве параметра строке только один раз
Напишите метод, определяющий все символы, встречающиеся в переданной в качестве...

Передача класса в качестве параметра
Возможно ли передать класс в качестве параметра определённой функции что бы она...

Передача функции в качестве параметра
Может кто помочь объяснить следующую часть кода: double...

Передача массива в качестве параметра
var etc2 = articles.Select(a => new TopicInfo { ...

Передача произвольной коллекции в качестве параметра
Добрый вечер! Объясните, пожалуйста, как можно передать коллекцию, реализующую...

2
kolorotur
Эксперт .NET
10486 / 8674 / 2157
Регистрация: 17.09.2011
Сообщений: 14,892
Завершенные тесты: 1
01.11.2017, 16:50 2
Чего-то не понятно: смысл делать метод, в котором производится обход всех возможных значений и сравнивается с искомым?
Почему бы просто не сделать это же сравнение безо всяких циклов?

Или если надо проверить, принадлежит ли указанное значение определенному перечислению, то почему не воспользоваться методом Enum.IsDefined?
1
titan4ik
119 / 97 / 19
Регистрация: 08.01.2017
Сообщений: 577
01.11.2017, 17:13  [ТС] 3
Фух, увидел ошибки - наружу из метода ничего не передается (только чрез печать на консоль) , но это не принципиально для данной темы.
И ещё, наверное нужно было методы не void, а Enum делать, тогда было бы проще и логичнее в целом и второй вариант был бы с двумя параметрами.

Добавлено через 5 минут
Цитата Сообщение от kolorotur Посмотреть сообщение
Или если надо проверить, принадлежит ли указанное значение определенному перечислению, то почему не воспользоваться методом Enum.IsDefined?
Это да. Так лучше.

Добавлено через 9 минут
То есть для сравнения значения на соответствие данному перечислению достаточно одного стандартного метода Enum.IsDefined
И никакой огород городить не нужно.
Но могут быть и другие причины передать тип перечисления в метод.
Ок. Спасибо.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.11.2017, 17:13

Хранение и передача метода в качестве параметра
Здравствуйте. Заранее прошу извинить, что создал одну и ту же тему в двух...

Передача методу объекта в качестве параметра
Уважаемые знатоки, как понимать Передача методу объекта в качестве параметра??...

Метод в качестве возвращаемого параметра
Никак не получается на C# написать функцию, возвращающую в качестве параметра...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru