Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.95/19: Рейтинг темы: голосов - 19, средняя оценка - 4.95
15 / 14 / 2
Регистрация: 15.01.2009
Сообщений: 55

Приведение к типу, определённому только во время исполнения

15.01.2009, 13:54. Показов 3956. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В приложении есть список объектов List<Объект> определённых следующим образом:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Объект {
}
public class Дорога : Объект {
    public enum Тип {
        Главная  = 1,
        Железная = 2,
    }
    public Тип тип;
}
public class Граница : Объект {
    public enum Тип {
        Области = 1,
        Района  = 3,
    }
    public Тип тип;
}
Во время исполнения этот список формируется из объектов обоих классов.
В другом месте программы происходит извлечение объектов из списка.
C#
1
2
Объект объект = список[номерОбъекта];
String тип    = объект.GetType().Name + "." + (объект as КЛАСС).тип.ToString();
Строка "тип" должна содержать значения "Дорога.Главная" или "Граница.Района". Но для этого нужно привести объект к типу "КЛАСС" (либо "Дорога" либо "Граница").

Есть способ это реализовать?

А если есть способ перенести переменную "тип" в базовый класс, то было бы вообще замечательно.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.01.2009, 13:54
Ответы с готовыми решениями:

Проверка вершины стека не принадлежность к определённому типу
Дорого всем времени суток.У меня возникла такая необходимость:у меня есть стек с элементами типа string,мне необходимо проверить вершину...

Нетривиальное приведение к типу
Доброго времени суток! Возник вопрос, прошу помощи... Суть проблемы: есть код (получение записей в таблице SQLite) ...

Cast<TResult> приведение к заранее неизвестному типу
Добрый день. У меня есть переменная result типа ArrayList. Привести ее к массиву типа string можно так: string mas =...

11
Администратор
 Аватар для mik-a-el
87818 / 53139 / 249
Регистрация: 10.04.2006
Сообщений: 13,761
15.01.2009, 13:59
Используйте дженерики.
0
15 / 14 / 2
Регистрация: 15.01.2009
Сообщений: 55
15.01.2009, 14:38  [ТС]
Приведите пожалуйста пример использования Generic-классов для данной задачи.
0
Комбайнёр
 Аватар для MAcK
1606 / 704 / 77
Регистрация: 27.05.2008
Сообщений: 2,535
15.01.2009, 16:32
C#
1
((Объект.Дорога)List.items[0]).Главная
0
1923 / 428 / 41
Регистрация: 12.07.2007
Сообщений: 2,062
16.01.2009, 03:28
Цитата Сообщение от -Dash- Посмотреть сообщение
если есть способ перенести переменную "тип" в базовый класс, то было бы вообще замечательно.
это есть и это вам и нужно.
C#
1
2
3
public class Объект {
    public Тип тип;  
}
Но придется сливать оба Enum`а в один. Лучше использовать объект, со свойством типа string.
0
15 / 14 / 2
Регистрация: 15.01.2009
Сообщений: 55
16.01.2009, 08:07  [ТС]
Цитата Сообщение от IT-Skyline Посмотреть сообщение
C#
1
((Объект.Дорога)List.items[0]).Главная
Заранее неизвестно будет ли объект иметь тип "Объект.Дорога" или "Объект.Граница". Это определяется только на момент исполнения приложения. В том то и проблема.

Добавлено через 4 минуты 54 секунды
Цитата Сообщение от Green Посмотреть сообщение
Но придется сливать оба Enum`а в один.
Если слить оба Enum'a, то задача становится тривиальной. Вот как раз сливать то их и не хотелось бы...
0
1923 / 428 / 41
Регистрация: 12.07.2007
Сообщений: 2,062
16.01.2009, 08:12
Цитата Сообщение от -Dash- Посмотреть сообщение
Если слить оба Enum'a, то задача становится тривиальной. Вот как раз сливать то их и не хотелось бы...
Ввести еще одну иерархию классов. Базовый со свойством типа строка, в нем будет название ("Главная","Района","Все чего угодно"). От него два потомка. Один для дорог, другой для района. У каждого свой конструктор. Вот в конструктор как раз и передавать нужные enum`ы.
0
15 / 14 / 2
Регистрация: 15.01.2009
Сообщений: 55
16.01.2009, 08:37  [ТС]
Первую часть задачи удалось решить использованием виртуального свойства типа String.
И всё же хотелось бы каким либо образом перенести переменную "тип" в родительский класс без объединения Enum'ов. В С++ такое сделать нереально в силу того, что эта переменная разных типов для каждого дочернего класса. Но может быть в C# есть механизмы для реализации этого?

Добавлено через 5 минут 55 секунд
Цитата Сообщение от Green Посмотреть сообщение
Ввести еще одну иерархию классов. Базовый со свойством типа строка, в нем будет название ("Главная","Района","Все чего угодно"). От него два потомка. Один для дорог, другой для района. У каждого свой конструктор. Вот в конструктор как раз и передавать нужные enum`ы.
В используемых Enum'ах есть пересекающиеся значения. Как видно из примера в первом сообщении "Главная" и "Области" имеют одно и то же числовое значение.

Добавлено через 15 минут 41 секунду
Вообще, смысл всего этого: удобство использования разработанного модуля. Чтобы с одной стороны программист, описывая объект класса "Дорога" использовал значения из Enum'а {Главная, Автомагистраль, Шоссе, Железная, ...}, описывая объект класса "Граница" использовал значения из Enum'а {Районная, Областная, Международная, ...}, а с другой стороны все эти объекты должны храниться в одном списке и иметь общие методы, в работе которых используются переменные с типом данных Enum'ов.
0
1923 / 428 / 41
Регистрация: 12.07.2007
Сообщений: 2,062
16.01.2009, 08:46
Цитата Сообщение от -Dash- Посмотреть сообщение
В используемых Enum'ах есть пересекающиеся значения. Как видно из примера в первом сообщении "Главная" и "Области" имеют одно и то же числовое значение.
И что? Вся программа это набор 0 и 1, но работает же. Не забывайте с# типизированный язык.

Цитата Сообщение от -Dash- Посмотреть сообщение
Вообще, смысл всего этого: удобство использования разработанного модуля.
Вот и вводите еще одну иерархию. Это даст вам также дополнительное преимущество при создании новых объектов с другой характеристикой, например, для объекта Город: Село, Город и т.д...)
0
15 / 14 / 2
Регистрация: 15.01.2009
Сообщений: 55
16.01.2009, 10:34  [ТС]
Задачу решил следующим кодом:
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
public class Объект {
    protected Enum _тип;
    public Enum тип {
        get { return _тип; }
        set { _тип = value; }
    }
    public String строка {
        get { return this.GetType().Name + "." + тип.ToString(); }
    }
}
public class Дорога : Объект {
    public enum Тип {
        Главная  = 1,
        Железная = 2,
    }
    public new Тип тип {
        get {
            if(!Enum.IsDefined(typeof(Тип), (Тип)_тип)) {
                throw new InvalidCastException("Операция приведения типа не может быть выполнена");
            }
            return (Тип)_тип;
        }
        set { _тип = value; }
    }
}
public class Граница : Объект {
    public enum Тип {
        Областная = 1,
        Районная  = 3,
    }
    public new Тип тип {
        get {
            if(!Enum.IsDefined(typeof(Тип), (Тип)_тип)) {
                throw new InvalidCastException("Операция приведения типа не может быть выполнена");
            }
            return (Тип)_тип;
        }
        set { _тип = value; }
    }
}
Теперь обращаясь к дочернему объекту через интерфейс базового можно увидеть корректную строку, в то же время при определении свойств дочернего объекта выводится именно тот Enum, который нужен.
Осталось добавить пару исключений, чтобы предотвратить различные нежелательные приведения типов, например:
C#
1
2
3
4
Дорога дорога = new Дорога();
дорога.тип = Дорога.Тип.Главная;
Объект объект = дорога;
объект.тип = Граница.Тип.Районная;
Всем спасибо за то, что навели меня на нужные мысли
0
1923 / 428 / 41
Регистрация: 12.07.2007
Сообщений: 2,062
16.01.2009, 10:57
Вот это место непонятно:
C#
1
2
3
4
5
6
7
8
    protected Enum _тип;
    public Enum тип {
        get { return _тип; }
        set { _тип = value; }
    }
    public String строка {
        get { return this.GetType().Name + "." + тип.ToString(); }
    }
Кто такой Enum?

C#
1
2
3
4
5
6
7
8
9
     public new Тип тип {  
         get {  
             if(!Enum.IsDefined(typeof(Тип), (Тип)_тип)) {  
                 throw new InvalidCastException("Операция приведения типа не может быть выполнена");  
             }  
             return (Тип)_тип;  
         }  
         set { _тип = value; }  
     }
а здесь if надо перенести из get в set


Это все рабочий код или пока на бумаге?
0
15 / 14 / 2
Регистрация: 15.01.2009
Сообщений: 55
16.01.2009, 11:52  [ТС]
Цитата Сообщение от Green Посмотреть сообщение
Кто такой Enum?
Enum в MSDN описывается как: Provides the base class for enumerations

Цитата Сообщение от Green Посмотреть сообщение
C#
1
2
3
4
5
6
7
8
9
public new Тип тип {    
    get {    
        if(!Enum.IsDefined(typeof(Тип), (Тип)_тип)) {    
            throw new InvalidCastException("Операция приведения типа не может быть выполнена");    
        }    
        return (Тип)_тип;    
    }    
    set { _тип = value; }    
}
а здесь if надо перенести из get в set
это уже сделано:
C#
1
2
3
4
5
get { return (Тип)_тип; }
set {
    Enum.IsDefined(typeof(Тип), _тип);
    _тип = value;
}
и в базовом классе:
C#
1
2
3
4
5
6
7
public Enum тип {
    get { return _тип; }
    set {
        Enum.IsDefined(this.GetType().GetNestedType("Тип"), value);
        _тип = value;
    }
}
Теперь исключения выскакивают именно так, как мне надо.
Цитата Сообщение от Green Посмотреть сообщение
Это все рабочий код или пока на бумаге?
Да, это рабочий код.

Добавлено через 14 минут 37 секунд
в третьей строке первого примера вместо "_тип" стоит "value". Ошибка Copy/Paste'а
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
16.01.2009, 11:52
Помогаю со студенческими работами здесь

Приведение переменной к типу данных SQL Server
Добрый день. Разрешите начинающему разбираться в C# задать вопрос: При попытке изменения клички Авто с помощью консольного интерфейса: ...

Приведение к типу
Почему в array нет поля класса а когда привожук типу a? using System; using System.Collections.Generic; using System.Linq; ...

Приведение к типу интерфейса
Ребят, помогите найти ответ на следующий вопрос: что выведет на экран следующий метод и почему? interface IMe { ...

Динамическое приведение к типу
Можно ли каким либо образом сделать приведение к какому либо типу, при условии что название типа будет известно только в ходе выполнения. ...

Приведение к первоначальному типу Object
День добрый! Есть два метода, отличаются только первой строкой, подскажите как их объединить? private void menuItem_Click(object...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru