Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/58: Рейтинг темы: голосов - 58, средняя оценка - 4.64
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5

Замена switch полиморфизмом

29.08.2012, 06:56. Показов 11810. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Читаю в данный момент книгу по рефакторингу, решил посмотреть свой старый код и переделать. Скажите, как можно заменить это switch? А то что-то в голову ничего не идет (может это потому, что не спал пару дней, не знаю):
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        private static ILevel GetLevel(int lev)
        {
            ILevel level;
            switch (lev)
            {
                case 2:
                    level = new Level2();
                    break;
                case 3:
                    level = new Level3();
                    break;
                case 4:
                    level = new Level4();
                    break;
                default:
                    level = new Level1();
                    break;
            }
            return level;
        }
Весь код региона:
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
84
85
86
87
88
89
90
91
92
93
94
private static ILevel GetLevel(int lev)
        {
            ILevel level;
            switch (lev)
            {
                case 2:
                    level = new Level2();
                    break;
                case 3:
                    level = new Level3();
                    break;
                case 4:
                    level = new Level4();
                    break;
                default:
                    level = new Level1();
                    break;
            }
            return level;
        }
 
        //Содержит код генерации барьеров для различных уровней
 
        #region Levels
 
        private interface ILevel
        {
            HashSet<Point> SetBarriers();
        }
 
        private class Level1 : ILevel
        {
            public HashSet<Point> SetBarriers()
            {
                return new HashSet<Point>();
            }
        }
 
        private class Level2 : ILevel
        {
            public HashSet<Point> SetBarriers()
            {
                var barriers = new HashSet<Point>();
                for (int i = 0; i < _size.Width; i++)
                {
                    barriers.Add(new Point(i, 0));
                    barriers.Add(new Point(i, _size.Height - 1));
                }
                for (int i = 0; i < _size.Height; i++)
                {
                    barriers.Add(new Point(0, i));
                    barriers.Add(new Point(_size.Width - 1, i));
                }
                return barriers;
            }
        }
 
        private class Level3 : ILevel
        {
            public HashSet<Point> SetBarriers()
            {
                var barriers = new HashSet<Point>();
                for (int i = 0; i < _size.Width/3; i++)
                {
                    barriers.Add(new Point(i, _size.Height/3));
                    barriers.Add(new Point(_size.Width - i - 1, _size.Height/3));
                    barriers.Add(new Point(i, (_size.Height*2)/3));
                    barriers.Add(new Point(_size.Width - i - 1, (_size.Height*2)/3));
                }
                return barriers;
            }
        }
 
        private class Level4 : ILevel
        {
            public HashSet<Point> SetBarriers()
            {
                var barriers = new HashSet<Point>();
                for (int i = 0; i < (_size.Width*2)/3; i++)
                {
                    barriers.Add(new Point(i, _size.Height/4));
                    barriers.Add(new Point(_size.Width - i - 1, (_size.Height*3)/4));
                }
                for (int i = 0; i < _size.Height/4; i++)
                {
                    barriers.Add(new Point((_size.Width*2)/3, i));
                    barriers.Add(new Point(_size.Width/3, _size.Height - i - 1));
                }
                barriers.Add(new Point((_size.Width*2)/3, _size.Height/4));
                return barriers;
            }
        }
 
        #endregion
по сути мне передают int число, а по нему я должен решить, какой уровень создать. Вопрос: можно ли без case обойтись? Единственный вариант, который приходит в голову - сделать словарь.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
29.08.2012, 06:56
Ответы с готовыми решениями:

Оправдана ли замена If на Switch
Всем привет! Я получаю ответ от сервера: string killer; killer = new StreamReader(response.GetResponseStream(),...

Замена if else на switch
Доброго времени суток. Нуждаюсь в помощи с лабораторной работой. Задание: написать программу, решающую данное уравнение, используя if...

Замена switch на if
Задание: Заменить в примере оператор switch структурой операторов if. Вопрос: Как можно заменить default??

9
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
29.08.2012, 08:04
Нормальная фабрика - где-то все равно должна проверка происходить, а свитч в данном случае эффективнее словаря будет.
1
Неадекват
 Аватар для freeba
1501 / 1237 / 248
Регистрация: 02.04.2010
Сообщений: 2,807
29.08.2012, 11:54
Эмм. А не проще было написать метод для генерации барьеров, а информацию как генерировать вынести в data-файлы. В этом случае код был бы проще.

Уровни можно было-бы хранить в словаре типа <№, Имя_Файла_Уровня>, в метод генерации блоков передаем имя файла, и он все генерит. Т.е. мы заменяем весь код региона на словарь и один метод, явный PROFIT.
1
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
29.08.2012, 18:54  [ТС]
В общем тупанул с методом, вот гораздо более простой вариант:
C#
1
2
3
4
5
6
7
8
9
10
private static ILevel GetLevel(int level)
        {
            switch (level)
            {
                case 2: return new Level2();
                case 3: return new Level3();
                case 4: return new Level4();
                default: return new Level1();
            }
        }
Добавлено через 13 минут
Вопрос такой. Может все это загнать как методы одного класса, например у класса Level сделать методы GetLevel1, GetLevel2... и потом как-то с помощью рефлексии вызывать метод
C#
1
2
3
4
5
HashSet<Point> SetBarriers(int level)
{
   ...
   return Invoke("GetLevel" + level);
}
я наверняка написал бредятину, потому что с рефлексией не работал, но мне кажется, что что-то такое можно провернуть.
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
31.08.2012, 00:01
Если можно без рефлексии, то лучше ее не применять.
Чем вас просто не устраивает например массив с делегатами?
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
31.08.2012, 00:04  [ТС]
turbanoff, да я думаю, может так оставить, или все же некрасиво? Вроде, добавление нового уровня сведется к написанию еще одного класса и добавление в этот метод еще одного return, и все.
0
Темная сторона .Net
 Аватар для Noob.net
592 / 489 / 39
Регистрация: 21.07.2012
Сообщений: 1,668
31.08.2012, 00:31
Можно объединить методы по создание объектов в массив и вызывать по имени.Будет без свитч.

Ну или медленная рефлексия)
C#
1
2
Type T = Type.GetType("Namespace.And.Your.TypeName");
object Obj = Activator.CreateInstance(T);
0
 Аватар для m0nax
1274 / 975 / 113
Регистрация: 12.01.2010
Сообщений: 1,971
31.08.2012, 13:43
Цитата Сообщение от Psilon Посмотреть сообщение
Добавлено через 13 минут
Вопрос такой. Может все это загнать как методы одного класса, например у класса Level сделать методы GetLevel1, GetLevel2... и потом как-то с помощью рефлексии вызывать метод
C#
1
2
3
4
5
HashSet<Point> SetBarriers(int level)
{
   ...
   return Invoke("GetLevel" + level);
}
я наверняка написал бредятину, потому что с рефлексией не работал, но мне кажется, что что-то такое можно провернуть.
а если рука дрогнет и получится метод GetLebel4() для нового уровня?
компилятор это радостно скушает, все будет отлично запускаться и работать, но вместо 4 уровня будет непонятно что без намека на причину ошибки
0
16 / 16 / 3
Регистрация: 16.08.2011
Сообщений: 62
31.08.2012, 15:53
Я бы решил эту проблему так. каждый класс помечаешь атрибутом с номером. К примеру DisplayName("1").
В начале работы программе или где-то в другой момент формируешь Dictionary<int, ILevel> с помощью рефлексии. В момент вызова метода делаешь
C#
1
return Dictionary<int, ILevel>[level]
1
1 / 1 / 0
Регистрация: 18.12.2013
Сообщений: 8
01.06.2015, 13:52
Избавиться от свитча, можно, с помощью делегатов:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Private delegate double LevelDelegate(ILevel level);
Private Dictionary<int, LevelDelegate > _levels;
_levels = new Dictionary<int, LevelDelegate >
{
{2, this.Level2},
{3, this.Level3},
{4, this.Level3}
};
public double PerformLevel (int op, ILevel level)
{
    if (!_levels.ContainsKey(op))
        throw new ArgumentException(string.Format("Level {0} is invalid", op), "op");
    return _ levels[op](level);
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
01.06.2015, 13:52
Помогаю со студенческими работами здесь

Замена if на switch
Задача. Это нужно сделать с помощью switch. ( Для натурального числа k вывести фразу “Мы нашли k грибов в лесу”, согласовав слово «гриб»...

Замена switch/case
Здравствуйте, я написал программу, теперь хочу чтобы по вводу в консоль 1 у меня выполнялся вот этот кусочек ...

Замена большого Switch
Привет, взглянув чуть-чуть наперед, и осознав что код может стать куда больше, появилась необходимость сократить это и сделать как-то...

Замена if-ов на switch case
В общем, было такое задание: Дана строка. Найдите в этой строке второе вхождение буквы f и выведите индекс этого вхождения. Если буква f...

Замена If на Switch вызвала ошибки
Создаю структуру, подключаю к ней txt файл, использовала if, все работало, решила поменять на switch начал ругаться Не понимаю, что...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
Использование значений реквизитов справочника в документе, с определенными условиями и правами
Maks 07.04.2026
1. Контроль срока действия договора Алгоритм из решения ниже реализован на примере нетипового документа "ЗаявкаНаРаботу", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если. . .
Доступность команды формы по условию
Maks 07.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: сделать доступной кнопку (команда формы "ЗавершитьСписание") при. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru