Кастинг базового класса в дочерний
От: snaphold  
Дата: 23.03.22 11:32
Оценка:
Тут задача вроде несложная но хочется красиво сделать ее.
На входе есть файл с сущностями которые все наследуются от одного базового класса (Parent).
Набор полей в файле фиксированный, просто есть поле Детерминатор которое показывает к какому дочернему классу сущность принадлежит.

Задача, распарсить этот файл, провести валидацию уже отдельно под каждый дочерний тип отдельно и сохранить в базе под каждый дочерний (Child) тип отдельно.

С проблемой какой столкнулся. Сделал парсинг файла который возвращает List<Parent> но вот как сделать красиво кастинг под каждый дочерний тип?
только так

List<Parent>.Select(a => new Child(a)) ?
Re: Кастинг базового класса в дочерний
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.03.22 11:50
Оценка:
Здравствуйте, snaphold, Вы писали:

S>Тут задача вроде несложная но хочется красиво сделать ее.

S>На входе есть файл с сущностями которые все наследуются от одного базового класса (Parent).
S>Набор полей в файле фиксированный, просто есть поле Детерминатор которое показывает к какому дочернему классу сущность принадлежит.
То есть структура дочерних классов тоже такая же, как и у Parent?
S>Задача, распарсить этот файл, провести валидацию уже отдельно под каждый дочерний тип отдельно и сохранить в базе под каждый дочерний (Child) тип отдельно.
А в базе структура колонок тоже везде одинаковая?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Кастинг базового класса в дочерний
От: snaphold  
Дата: 23.03.22 12:02
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, snaphold, Вы писали:


S>>Тут задача вроде несложная но хочется красиво сделать ее.

S>>На входе есть файл с сущностями которые все наследуются от одного базового класса (Parent).
S>>Набор полей в файле фиксированный, просто есть поле Детерминатор которое показывает к какому дочернему классу сущность принадлежит.
S>То есть структура дочерних классов тоже такая же, как и у Parent?

да. просто добавляются некоторые поля в одном чайлде

S>>Задача, распарсить этот файл, провести валидацию уже отдельно под каждый дочерний тип отдельно и сохранить в базе под каждый дочерний (Child) тип отдельно.

S>А в базе структура колонок тоже везде одинаковая?

да. в одном чайлде надо еще записать данные в другую таблицу
Re: Кастинг базового класса в дочерний
От: vmpire Россия  
Дата: 23.03.22 12:07
Оценка: +1
Здравствуйте, snaphold, Вы писали:


S>С проблемой какой столкнулся. Сделал парсинг файла который возвращает List<Parent> но вот как сделать красиво кастинг под каждый дочерний тип?

.Cast<Child>()
Re[2]: Кастинг базового класса в дочерний
От: snaphold  
Дата: 23.03.22 12:17
Оценка:
Здравствуйте, vmpire, Вы писали:

V>Здравствуйте, snaphold, Вы писали:



S>>С проблемой какой столкнулся. Сделал парсинг файла который возвращает List<Parent> но вот как сделать красиво кастинг под каждый дочерний тип?

V>.Cast<Child>()

я тоже ожидал что так можно и что отсутствующие поля в Паренте будут дефолтными.
однако

Unable to cast object of type 'ConsoleApp1.Parent' to type 'ConsoleApp1.Child'.

Re: Кастинг базового класса в дочерний
От: karbofos42 Россия  
Дата: 23.03.22 12:24
Оценка: +2
Здравствуйте, snaphold, Вы писали:

S>Тут задача вроде несложная но хочется красиво сделать ее.

S>На входе есть файл с сущностями которые все наследуются от одного базового класса (Parent).
S>Набор полей в файле фиксированный, просто есть поле Детерминатор которое показывает к какому дочернему классу сущность принадлежит.

S>Задача, распарсить этот файл, провести валидацию уже отдельно под каждый дочерний тип отдельно и сохранить в базе под каждый дочерний (Child) тип отдельно.


S>С проблемой какой столкнулся. Сделал парсинг файла который возвращает List<Parent> но вот как сделать красиво кастинг под каждый дочерний тип?


Так пусть парсер и создаёт сразу new Child на основе детерминатора, а не для всех бездумно new Parent, а потом разберёмся.

S>только так


S>List<Parent>.Select(a => new Child(a)) ?


Если устроит тяп-ляп и у всех данные одни и те же хранятся, то можно и так.
Главное — чтобы потом не было сюрприза, что такое-то свойство у Child теряется, т.к. по сути считывается Parent и его свойства и плевать что там в каком наследнике ещё добавилось.
Re[2]: Кастинг базового класса в дочерний
От: Mihas  
Дата: 23.03.22 12:32
Оценка: +1
Здравствуйте, karbofos42, Вы писали:

K>Так пусть парсер и создаёт сразу new Child на основе детерминатора, а не для всех бездумно new Parent, а потом разберёмся.

++
тогда и OfType<Child>().Cast<Child>() сработает как ожидалось
Re[2]: Кастинг базового класса в дочерний
От: snaphold  
Дата: 23.03.22 12:39
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>Здравствуйте, snaphold, Вы писали:


S>>Тут задача вроде несложная но хочется красиво сделать ее.

S>>На входе есть файл с сущностями которые все наследуются от одного базового класса (Parent).
S>>Набор полей в файле фиксированный, просто есть поле Детерминатор которое показывает к какому дочернему классу сущность принадлежит.

S>>Задача, распарсить этот файл, провести валидацию уже отдельно под каждый дочерний тип отдельно и сохранить в базе под каждый дочерний (Child) тип отдельно.


S>>С проблемой какой столкнулся. Сделал парсинг файла который возвращает List<Parent> но вот как сделать красиво кастинг под каждый дочерний тип?


K>Так пусть парсер и создаёт сразу new Child на основе детерминатора, а не для всех бездумно new Parent, а потом разберёмся.


парсер заточен чисто под парсинг файлов. в нем нет логики под разные типы.
Ему на вход даешь какой тип данных надо получить и дальше он берет поля этой сущности и ищет колонки с таким названием в файле
Re[3]: Кастинг базового класса в дочерний
От: vaa  
Дата: 23.03.22 13:02
Оценка:
Здравствуйте, Mihas, Вы писали:

M>Здравствуйте, karbofos42, Вы писали:


K>>Так пусть парсер и создаёт сразу new Child на основе детерминатора, а не для всех бездумно new Parent, а потом разберёмся.

M>++
M>тогда и OfType<Child>().Cast<Child>() сработает как ожидалось

будет пустой список. OfType отфильтрует список.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[3]: Кастинг базового класса в дочерний
От: vmpire Россия  
Дата: 23.03.22 13:06
Оценка:
Здравствуйте, snaphold, Вы писали:

S>>>С проблемой какой столкнулся. Сделал парсинг файла который возвращает List<Parent> но вот как сделать красиво кастинг под каждый дочерний тип?

V>>.Cast<Child>()

S>я тоже ожидал что так можно и что отсутствующие поля в Паренте будут дефолтными.

S>однако
S>

S>Unable to cast object of type 'ConsoleApp1.Parent' to type 'ConsoleApp1.Child'.

Значит, у вас там реально в списке не Child лежит, иначе бы скастилось. А раз так, то или ошибка в формировании списка, или Вам нужен не кастинг, а конвертация.
По каким правилам конвертить — Вам виднее, это же ваши классы.
Re[3]: Кастинг базового класса в дочерний
От: karbofos42 Россия  
Дата: 23.03.22 13:09
Оценка:
Здравствуйте, snaphold, Вы писали:

S>Здравствуйте, karbofos42, Вы писали:


K>>Здравствуйте, snaphold, Вы писали:


S>>>Тут задача вроде несложная но хочется красиво сделать ее.

S>>>На входе есть файл с сущностями которые все наследуются от одного базового класса (Parent).
S>>>Набор полей в файле фиксированный, просто есть поле Детерминатор которое показывает к какому дочернему классу сущность принадлежит.

S>>>Задача, распарсить этот файл, провести валидацию уже отдельно под каждый дочерний тип отдельно и сохранить в базе под каждый дочерний (Child) тип отдельно.


S>>>С проблемой какой столкнулся. Сделал парсинг файла который возвращает List<Parent> но вот как сделать красиво кастинг под каждый дочерний тип?


K>>Так пусть парсер и создаёт сразу new Child на основе детерминатора, а не для всех бездумно new Parent, а потом разберёмся.


S>парсер заточен чисто под парсинг файлов. в нем нет логики под разные типы.

S>Ему на вход даешь какой тип данных надо получить и дальше он берет поля этой сущности и ищет колонки с таким названием в файле

расширить парсинг, чтобы умел и разные типы.
Можно хоть Func<string, object> передавать ему, который по входному детерминатору вернёт объект нужного типа для последующего заполнения данными.
либо парсинг уже пусть хоть какой-нибудь DataTable обезличенный возвращает, а из таблички уже в другом месте формировать объекты Parent, Child, ChildChild, или какие там ещё нужно, а их потом в БД записывать.

Кастовать объект родительского класса в дочерний не получится, тут придётся новый объект создавать нужного типа.
Может тут наследование и не нужно, а можно заменить его на композицию?
Сначала из парсера получаем данные, которые для всех одинаковые и записаны в Parent, а потом получаем новые коллекции Child1, Child2,... которые содержат в себе свойство Parent и дополнительные какие-то штуки, которые потом по-разному в БД записываются.
Re: Кастинг базового класса в дочерний
От: Ночной Смотрящий Россия  
Дата: 24.03.22 09:13
Оценка:
Здравствуйте, snaphold, Вы писали:

S>С проблемой какой столкнулся. Сделал парсинг файла который возвращает List<Parent> но вот как сделать красиво кастинг под каждый дочерний тип?

S>только так

S>List<Parent>.Select(a => new Child(a)) ?


Не очень понятны юзкейсы. Если парсер выдает экземляры Parent, то зачем их заворачивать потом в Child? Зачем хранить в БД в разных таблицах, если уже есть дискриминант и состав полей частично или полностью совпадает? Что ты понимаешь под кастингом?
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[2]: Кастинг базового класса в дочерний
От: snaphold  
Дата: 24.03.22 13:56
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, snaphold, Вы писали:


S>>С проблемой какой столкнулся. Сделал парсинг файла который возвращает List<Parent> но вот как сделать красиво кастинг под каждый дочерний тип?

S>>только так

S>>List<Parent>.Select(a => new Child(a)) ?


НС>Не очень понятны юзкейсы. Если парсер выдает экземляры Parent, то зачем их заворачивать потом в Child? Зачем хранить в БД в разных таблицах, если уже есть дискриминант и состав полей частично или полностью совпадает? Что ты понимаешь под кастингом?


в файле список граждан одного гос-ва с одинаковым набором полей, но разного типа для системы.
есть пенсионеры, студенты, обычные рабочие.
надо их провалидировать по разному для выдачи кредита, и потом сложить в общие таблицы, но в случае студентов к примеру есть доп.таблицы
Re[3]: Кастинг базового класса в дочерний
От: Ночной Смотрящий Россия  
Дата: 24.03.22 14:02
Оценка: +1
Здравствуйте, snaphold, Вы писали:

S>в файле список граждан одного гос-ва с одинаковым набором полей, но разного типа для системы.

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

Это не отвечает на вопрос зачем тебе вообще понадобились классы-наследники.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[4]: Кастинг базового класса в дочерний
От: snaphold  
Дата: 24.03.22 14:20
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, snaphold, Вы писали:


S>>в файле список граждан одного гос-ва с одинаковым набором полей, но разного типа для системы.

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

НС>Это не отвечает на вопрос зачем тебе вообще понадобились классы-наследники.


специфические поля есть у студента или пенсионера которые участвуют в валидации этих сущностей или которые потом кладутся в отд таблицы.
изначально если что был одинй широкий класс. но писать кучу ифов надоело
Re[3]: Кастинг базового класса в дочерний
От: karbofos42 Россия  
Дата: 24.03.22 15:46
Оценка:
Здравствуйте, snaphold, Вы писали:

S>Здравствуйте, Ночной Смотрящий, Вы писали:


НС>>Здравствуйте, snaphold, Вы писали:


S>>>С проблемой какой столкнулся. Сделал парсинг файла который возвращает List<Parent> но вот как сделать красиво кастинг под каждый дочерний тип?

S>>>только так

S>>>List<Parent>.Select(a => new Child(a)) ?


НС>>Не очень понятны юзкейсы. Если парсер выдает экземляры Parent, то зачем их заворачивать потом в Child? Зачем хранить в БД в разных таблицах, если уже есть дискриминант и состав полей частично или полностью совпадает? Что ты понимаешь под кастингом?


S>в файле список граждан одного гос-ва с одинаковым набором полей, но разного типа для системы.

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

Создаём отдельный тип Гражданин, который используется как DTO для получения результата работы парсера.
Пишем код, который из коллекции граждан сформирует коллекции студентов, пенсионеров и т.д. (я так понимаю, что не нужно их по сути в общей коллекции держать)
Далее уже эти коллекции обрабатываем как там нужно, дополняем данными и т.п.
Re[5]: Кастинг базового класса в дочерний
От: Sinclair Россия https://github.com/evilguest/
Дата: 24.03.22 16:28
Оценка:
Здравствуйте, snaphold, Вы писали:
S>специфические поля есть у студента или пенсионера которые участвуют в валидации этих сущностей или которые потом кладутся в отд таблицы.
S>изначально если что был одинй широкий класс. но писать кучу ифов надоело
Пихать логику в entity-классы — плохая идея, есличо.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: Кастинг базового класса в дочерний
От: Ночной Смотрящий Россия  
Дата: 24.03.22 16:54
Оценка:
Здравствуйте, snaphold, Вы писали:

S>специфические поля есть у студента или пенсионера которые участвуют в валидации этих сущностей или которые потом кладутся в отд таблицы.

S>изначально если что был одинй широкий класс. но писать кучу ифов надоело

Не пиши кучу ifов, используй switch.
А на что ты хочешь их заменить в случае наследников? На виртуальные методы? Визитор?
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[6]: Кастинг базового класса в дочерний
От: vaa  
Дата: 25.03.22 05:10
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, snaphold, Вы писали:

S>>специфические поля есть у студента или пенсионера которые участвуют в валидации этих сущностей или которые потом кладутся в отд таблицы.
S>>изначально если что был одинй широкий класс. но писать кучу ифов надоело
S>Пихать логику в entity-классы — плохая идея, есличо.

сущность не должна обладать поведением?
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re: Кастинг базового класса в дочерний
От: vaa  
Дата: 25.03.22 05:19
Оценка:
Здравствуйте, snaphold, Вы писали:

S>С проблемой какой столкнулся. Сделал парсинг файла который возвращает List<Parent> но вот как сделать красиво кастинг под каждый дочерний тип?

S>только так

S>List<Parent>.Select(a => new Child(a)) ?


Во время парсинга сразу создавать нужный тип самое лучшее.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.