Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
 Аватар для xChernobyl
6 / 6 / 0
Регистрация: 07.02.2019
Сообщений: 54
.NET Core

Каст базового типа к типу класса-наследника

25.04.2020, 22:01. Показов 2396. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток. Вопрос такой: у меня есть обойбщенный класс, мэнеджер сессий

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class SessionManager<TSession> where TSession : class, INetSession
{
//Сессии хранятся вот в таком виде:
private ConcurrentDictionary<int, TSession> _sessions;
//
public SessionManager(ISessionFactory factory)
{
//... тут инициализация коллекции сессий и других членов класса
}
 
public TSession CreateSession()
{
//... тут через вызов обобщенного фабричного метода создается инстанс сессии (обобщенный аргумент передаваемый в фабрику - тот же TSession).
}
}
Сессии хранятся в виде ConcurrentDictionary<int, TSession>.

Во многих источниках утверждается (к примеру https://stackoverflow.com/ques... s/25653977) что кастить экземпляры базового класса к типу класса наследника нельзя, но вот у меня это получается вот таким вот образом:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
      
public bool TryGetSessionById<TDesiredSessionType>(out TDesiredSessionType session, int id)
            where TDesiredSessionType : class, INetSession
        {
            session = default;
 
            if (!_sessions.TryGetValue(id, out TSession tmp))
                return false;
 
            session = tmp as TDesiredSessionType;
 
            return session != default;
        }
Сам мэнеджер сессий обьявляется и инициализируется таким образом:

C#
1
SessionManager<SessionBase> SessionManager = new SessionManager<SessionBase>();

Т.е. тип коллекции хранимой в SessionManager - ConcurrentDictionary<int, SessionBase>, но реальные экземпляры которые туда добавляются (фабрикой) имеют другой тип (унаследованный от SessionBase).

Собственно вопрос в том, почему это вообще работает.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
25.04.2020, 22:01
Ответы с готовыми решениями:

Как сделать явное приведения переменной типа класса-наследника к типу базового класса?
Читал, что для этого нужно явное приведение к типу, но на практике выдаёт ошибку. Вот код: using System; using System.Linq; namespace...

.net core 3.1 / каст коллекций к типу наследника
Доброго времени суток. Вот всё немогу понять почему нельзя кастануть коллекцию к типу класса наследника. Вообщем проще показать на коде....

Создание экземпляра класса-наследника для переменной с типом базового класса
Подскажите чайнику как создается экземпляр класса BC BaseClass BC = new DerivedClass(); Вопрос: BC - это экземпляр класса BaseClass...

3
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
25.04.2020, 22:57
Цитата Сообщение от xChernobyl Посмотреть сообщение
Во многих источниках утверждается что кастить экземпляры базового класса к типу класса наследника нельзя
По ссылке нигде это не утверждается.
Напротив, утверждается там следующее:
As long as the object is actually a SkyfilterClient, then a cast should work.
У вас та же ситуация: если объект имеет тип TDesiredSessionType, то естественно каст сработает.

Другое дело, что если в обобщенном классе/методе вам приходится делать каст обобщенного типа к конкретному, то у вас серьезная проблема с выбранным подходом.
1
 Аватар для xChernobyl
6 / 6 / 0
Регистрация: 07.02.2019
Сообщений: 54
25.04.2020, 23:57  [ТС]
Т.е. касты такого рода не должны существовать в принцыпе, или кастать стоит вне обобщенного класса?

Я имею в виду что-то такое:

C#
1
2
   engine.SessionManager.TryGetSessionById(out SessionBase sess, session.ID);
            SpecificSession sess = sess as SpecificSession;
TryGetSessionById больше не обобщенный.
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
26.04.2020, 01:10
Лучший ответ Сообщение было отмечено xChernobyl как решение

Решение

Цитата Сообщение от xChernobyl Посмотреть сообщение
касты такого рода не должны существовать в принцыпе
Если обобщенный тип приходится кастить к конкретному, то зачем вообще нужен обобщенный тип?
Обобщенние подразумевает возможность работать с любымы типами.

Цитата Сообщение от xChernobyl Посмотреть сообщение
Я имею в виду что-то такое
Тут каст может быть оправдан, хотя попахивает плохой продуманностью интерфейсов.
Если возвращается SpecificSession, то и делайте выходной параметр соответствующим типом.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
26.04.2020, 01:10
Помогаю со студенческими работами здесь

Как обратиться из конструктора базового абстрактного класса к свойству-массиву класса наследника
Добрый день. Подскажите как обратиться из конструктора базового абстрактного класса к свойству-массиву из класса наследника. Вроде бы...

Конструирование наследника из экземпляра базового типа
Доброго времени суток. Есть 2 класса. Person и Student. У Person поля имя, фамилия, пол и тд. У Student - курс, # группы,...

Как привести объект базового типа к унаследованному типу
class MyList: List { } class Program { static void Main(string args) { List l = new List...

Вызов переопределенного метода класса наследника из базового класса
Предположим есть два класа: public class A { /* ... некая дополнительная реализация.... */ ...

Перебор элементов вектора базового класса с приведением к типу наследника
Добрый день, уважаемые коллеги Подскажите как правильно выполнить приведение типов. Есть базовый класс Item: #ifndef...


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это дополнительная запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru