Здравствуйте, undo75, Вы писали:
u> для прикладника он вообще нужен? ни одной задачи с потолка не смог придумать.
Например, для байдинга чего-нибудь к чему-нибудь. Вот например http рутинг предлагается делать так:
Routes::Post(router, "/users/:id", Routes::bind(&UsersApi::getUserId, this));
...
void UsersApi::getUserId(const Rest::Request& request, Http::ResponseWriter response)
{
auto id = request.param(":id").as<int>();
...
в яп с рефлексией будет просто
void UsersApi::getUserId(int id) {
}
и проверка соответствия шаблона "/users/:id" сигнатуре метода будет происходить в момент байндинга (т.е. запуска сервиса), а не во время работы этого метода (т.е. когда пользователь кликнет соответствующую кнопку).
Здравствуйте, undo75, Вы писали:
W>>А как же вот это вот все: побегать по названиям пропертей / методов объектов (например ваял как-то тестраннер, который по содержимому импортов в сборках определял, в каком конкретно тестфреймворке запускать тестики), сгенерить-запулить "на лету" какой-нить код в виде пользовательского скрипта? и еще 1001 применение?
U>а нафиг это все, ели по большому счету нужно джейсоны туда сюда гонять, да запросы в базу писать? упрощенно если.
Потому и нужно. Например, если у вас хрен-знает-сколькилион таких методов, с тз разработки проще сделать это именно через метапрограммирование
Вместо выписывания тысяч методов, и тестирования! вам нужен один конфиг/дсл/скрипт/итд.
можно пойти иначе — выписывать все по кусочку. Только вот стоимость разработки и поддержки на мой взгляд ну не очень.
Единственное, на что можно сетовать — кодогенерация это интрузивная вещь, избавиться от неё довольно трудно, в отличие от обычного дублирующегося кода.
SP>>ну и когда добавится новое поле (н-р Surname) придётся менять все методы. Бред. Точнее в С++ как-то так и едят этот кактус, но это явно не то, к чему надо стремиться
U>а как и где это обходится?
Если известно, что класс описывает "плоские" объекты, в которых свойства соответствуют хранимым атрибутам (а не рантайм-состоянию со сложной эволюцией), то его можно сконструировать гораздо компактнее:
public record Person(string FirstName, string LastName);
Это приведёт не только к объявлению свойств FirstName и LastName и публичного конструктора с одноименными аргументами, но и к автоматическому порождению метода Equals, который будет устроен примерно так, как вы показывали.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, undo75, Вы писали:
U>для прикладника он вообще нужен? ни одной задачи с потолка не смог придумать. U>не ну я понимаю, орм там всякие. для прикладника нафига?
Здравствуйте, Wolverrum, Вы писали: W>Свой, более лутшый Спринг и Энтити наваять
Это уже не прикладник. Это платформист.
Платформисту рефлексия — лучший друг, товарищ и брат. Также, как шаблоны, перегрузки операторов и функций, функции высшего порядка, и прочие сантехнические инструменты.
А прикладник — он кнопку нажал, говно смылось. Всё.
P.S. Один мой коллега построил себе дом, завёл систему умного дома. Смеялся над типичными внедряльщиками таких систем. "Они спрашивают: сколько у вас будет сценариев освещения?"
Ему очевидно, что основных "сценариев" для любого освещения всего два: "сделай поярче" и "сделай потемнее". А вот эти все "просмотр кино"/"видеозвонок другу"/"семейный ужин от 2х до 4х человек" — наркомания, которой невозможно пользоваться. Точно так же, как приборной панелью с 38 кнопками типа "нижняя подсветка в винном шкафу" и "софиты юго-запад".
Всё, что мы пилим — это способы борьбы со сложностью. Все несущественные подробности нужно убирать с глаз долой.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
U>это тоже считаю не обоснованным. к примеру в одном из мест был написан инструмент, делающий настройки для различных объектов. хранились в базе. и уверен на 100% что такое решение куда быстрее рефлекшена. а для отладки гораздо прозрачнее..
Главная проблема рефлекшена даже не в скорости, а в надежности.
Если программа устроена так, что банальный рефакторинг с переименованием класса или поля может напрочь сломать логику программы — это опасно и нехорошо. Атрибуты частично решают проблему, но все равно кривовато.
U>public class Person
U>{
U> public string FirstName { get; set; }
U> public string LastName { get; set; }
U> public override bool Equals(object obj)
U> {
U> if (obj == null) return false;
U> if (GetType() != obj.GetType()) return false;
U> Person other = (Person)obj;
U> return FirstName == other.FirstName && LastName == other.LastName;
U> }
U> public override int GetHashCode()
U> {
U> return FirstName.GetHashCode() ^ LastName.GetHashCode();
U> }
U>}
U>
ну и когда добавится новое поле (н-р Surname) придётся менять все методы. Бред. Точнее в С++ как-то так и едят этот кактус, но это явно не то, к чему надо стремиться
Здравствуйте, sergii.p, Вы писали:
SP>Можно конечно без этого. В С++ например до сих пор без рефлексии как-то обходятся. Но это просто ещё один инструмент, который иногда может улучшить код. В том же C++ находятся некоторые, которые говорят, что шаблоны не нужны. Ну да, 95% шаблоны не нужны, они их просто используют. Но знать инструмент и уметь его применять надо.
Если делаешь сериализацию без рефлексии, приходится каждое поле структуры дважды описывать: один раз в самом описании структуры и второй раз для сериялизатора.
А когда есть два параллельных описания одного и того же, рано или поздно они расползутся...
Здравствуйте, undo75, Вы писали:
U>п.с. навеяно текущим местом работы, где на нем вообще все ) из-за этого отладка сильно затруднена.... ничего сложного, но все через жопу делается и занимает кучу времени. имхо выбор был мягко говоря не обоснован. видимо на истоках был юноша со взглядом горящим, который про это прочитал и его кто-то послушал. и панеслась... других предположений у меня нет U>в моей практике потребовалось лишь один раз.
А что, прикладной код не надо структурировать, не надо управлять сложностью? С другими компонентами не нало интегрироваться, не надо инструментировать свой код для логирования, отладки, мониторинга,перформанса итд?
Рефлексия это еще один иструмент, позволяет отделять мух от котлет.
Вам прежде всего тяжело, потому что вы прошли мимо этой темы.
Так часто бывает — один навесит атрибут, а другой пытается отладчиком постичь это намерение. Так не работает.
Если у вас кругом рефлексия, то нужно не отладчиком работать, а выяснять логику этой всей рефлексии, какие аспекты она применяет.
Вполне может оказаться так, что дело именно в том, что вы привыкли делать все по старинке.
Здравствуйте, undo75, Вы писали:
u>>> поэтому вопрос — как обстоит дело с отладкой? U>·>Я не понял о каком именно из "яп с рефлексией" ты спрашиваешь. В java, например, с отладкой всё просто замечательно.
U>извини. вот у тебя динамически формируется класс. фиг знает как там на джаве, предполагаю, что как и везде. где точку останова ставить? )
Похоже под рефлексией вы называете system.reflection куда в дотнете понапихали чуть не все подряд
Расскажите, какая задача решается кодогенерацией?
Вам достаточно переделать кодогенератор таким образом, что бы вместо простыней генерировал вызов утилиты. Эту утилиту можно покрыть тестами, и в неё вы можете поставить точку останова. Т.е. минимальные изменения, достаточно безопасные.
Здравствуйте, undo75, Вы писали:
U>дак просто есть куча других путей для решения задач. зачем усложнять все? причем вообще все.
Без конкретики — ничего не ясно. вы даже не ответили, с чем именно проблема, с рефлексией или с кодогенерацией.
Усложнять можно вообще везде где угодно, с любым подходом. У каждого инструмента есть границы применимости.
Если вы инструментами не владеете, то подозреваю, проделываете раз в 100 больше лишней работы.
Это все ровно ничего не говорит о том, что так или не так с вашим проектом
И у рефлексии, и у кодогенерации есть бенефиты — сокращают количество рукописного кода в десятки раз.
Если у вас на проекте чтото не так пошло, варианты
1. вы не умеете этим пользоваться — с ваших слов, у вас нет опыта
2. товарищ, который писал, не умел этим пользоваться — ваше предположение
3. цели, масштабы проекта изменились
Здравствуйте, undo75, Вы писали:
U>для прикладника он вообще нужен?
Для прикладника — нет, не нужен.
Задачи рефлекшна — подготовка DSL.
Как раз для того, чтобы прикладник писал поменьше.
Все сценарии, описанные в топике — это как раз именно такие примеры.
В языках "без рефлекшна" прикладник вынужден объяснять платформе, что делать с его типом данных, императивным кодом*:
class CMyObject : public CObject
{
public:
int x, y;
void Serialize(CArchive &ar)
{
CObject::Serialize(ar);
if (ar.IsStoring())
ar << x;
else
ar >> x;
}
}
В языках "с рефлекшном" платформа в состоянии самостоятельно выяснить, из чего состоит СMyObject и сериализовать его, или сгенерировать для него форму редактирования, или сохранить его в реляционную СУБД, или построить для него операторы == и !==. Прикладнику об этом задумываться противопоказано. Ему важно знать, каким атрибутом отключить сериализацию CMyObject::y; а как именно это работает — то ли рефлекшном, то ли компайл-тайм магией — дело десятое. Если прикладник вынужден об этом думать — значит, реализация неудачная. Прикладнику надо
[Serializable]
public class MyObject {
... никакого boilerplate про сериализацию - только прикладная логика, уникальная для этого класса.
}
* пример умозрительный, иллюстративный. Я знаю, что конкретно на этом языке можно решить эту задачу и без рефлекшна, и без прямой императивщины в прикладном коде.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
для прикладника он вообще нужен? ни одной задачи с потолка не смог придумать.
не ну я понимаю, орм там всякие. для прикладника нафига?
в своей практике применял, только когда изучал
п.с. навеяно текущим местом работы, где на нем вообще все ) из-за этого отладка сильно затруднена.... ничего сложного, но все через жопу делается и занимает кучу времени. имхо выбор был мягко говоря не обоснован. видимо на истоках был юноша со взглядом горящим, который про это прочитал и его кто-то послушал. и панеслась... других предположений у меня нет
в моей практике потребовалось лишь один раз.
была библиотека и требовалось дернуть закрытый метод. без него ну вообще никак. исходников не было. и все. за 20 лет практики..
Здравствуйте, undo75, Вы писали:
U>для прикладника он вообще нужен? ни одной задачи с потолка не смог придумать. U>не ну я понимаю, орм там всякие. для прикладника нафига?
(де-)сериализация, инструменты для отладки. Больше ничего в голову не приходит.
_____________________
С уважением,
Stanislav V. Zudin
U>в моей практике потребовалось лишь один раз. U>была библиотека и требовалось дернуть закрытый метод. без него ну вообще никак. исходников не было. и все. за 20 лет практики..
я так понимаю, вопрос в контексте .NET.
Из вынужденных хаков:
1) работа с приватными методами сторонней библиотеки
2) использовать библиотеку из .net большей версии в проекте меньшей версии
В остальном: (де)сериализация.
Что-то ещё по мелочи..
Здравствуйте, undo75, Вы писали:
U>для прикладника он вообще нужен? ни одной задачи с потолка не смог придумать. U>не ну я понимаю, орм там всякие. для прикладника нафига?
Думаю нет, для прикладного программирования не нужно.
Прикладного в том смысле, что программист пишет программу для не-программистов.
Я видел разумное использование только в контексте "от программистов для дугих программистов",
т.е. библиотеки по сути, или инструменты какие-нибудь, типа кастомные аттрибуты, шаблоны, кодогенераторы.
ну если в двух словах и к месту и ни к месту. вообще везде. идея у них в кастомизации коробки. это в двух словах. причем кастомизации не только для пользователей, но и для программистов. написана масса шаблонизаторов на все случаи жизни ) почему визард в студии не написали тогда — для меня загадка. только консоль. только хардкор...
bnk>Я видел разумное использование только в контексте "от программистов для дугих программистов", bnk>т.е. библиотеки по сути, или инструменты какие-нибудь, типа кастомные аттрибуты, шаблоны, кодогенераторы.
это тоже считаю не обоснованным. к примеру в одном из мест был написан инструмент, делающий настройки для различных объектов. хранились в базе. и уверен на 100% что такое решение куда быстрее рефлекшена. а для отладки гораздо прозрачнее..
Здравствуйте, undo75, Вы писали:
U>в моей практике потребовалось лишь один раз. U>была библиотека и требовалось дернуть закрытый метод. без него ну вообще никак. исходников не было. и все. за 20 лет практики..
я использовал в логировании. Вроде по факту задача сериализации. Но несколько хитрее. И сохранение в файл. Когда у вас самописный формат и всякие JsonSerializer не подходят.
Можно конечно без этого. В С++ например до сих пор без рефлексии как-то обходятся. Но это просто ещё один инструмент, который иногда может улучшить код. В том же C++ находятся некоторые, которые говорят, что шаблоны не нужны. Ну да, 95% шаблоны не нужны, они их просто используют. Но знать инструмент и уметь его применять надо.
Я вот не знаю, как в С# принято делать метод Equals? Ручками писать все поля? Ведь так и ошибиться можно. А с рефлексией это всё делается в пару строчек и намного безопаснее. Ну может немного больше писать, если заморочиться на скорости.
Вообще я вот считаю, что рефлексия должна быть времени компиляции. Это бы избавило от многих проблем отладки и скорости. Но Java и C# уже только могила исправит.
SP>Я вот не знаю, как в С# принято делать метод Equals? Ручками писать все поля? Ведь так и ошибиться можно. А с рефлексией это всё делается в пару строчек и намного безопаснее. Ну может немного больше писать, если заморочиться на скорости.
как-то так
В C# есть несколько способов реализации метода Equals(), и выбор зависит от конкретной ситуации. Вот некоторые из них:
1. Переопределение метода Equals(object)
— Самый общий подход, который позволяет сравнивать объекты вашего класса с любыми другими объектами.
— Важно! Переопределить этот метод нужно всегда, если вы переопределяете GetHashCode().
— Приоритет: 1) Сравнение с null; 2) Сравнение типов; 3) Вызов метода Equals(object) у базового класса.
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public override bool Equals(object obj)
{
if (obj == null) return false;
if (GetType() != obj.GetType()) return false;
Person other = (Person)obj;
return FirstName == other.FirstName && LastName == other.LastName;
}
public override int GetHashCode()
{
return FirstName.GetHashCode() ^ LastName.GetHashCode();
}
}
2. Переопределение метода Equals(T other)
— Используется для сравнения объектов вашего класса с объектами того же типа.
— Обеспечивает более точный и читаемый код.
— Важно! Должен использоваться только в дополнение к Equals(object).
public class Person
{
// ... (другие свойства и методы) ...public bool Equals(Person other)
{
if (other == null) return false;
return FirstName == other.FirstName && LastName == other.LastName;
}
}
3. Использование IEquatable<T>
— Интерфейс IEquatable<T> предоставляет метод Equals(T other) для сравнения объектов с объектами того же типа.
— Важно! Обычно используется в сочетании с переопределением Equals(object) и GetHashCode().
— Преимущества:
— Повышенная типизация.
— Более явный намек на поведение сравнения.
— Поддержка стандартных методов для сравнения коллекций, например, List.Contains() и Dictionary.ContainsKey().
public class Person : IEquatable<Person>
{
// ... (другие свойства и методы) ...public bool Equals(Person other)
{
if (other == null) return false;
return FirstName == other.FirstName && LastName == other.LastName;
}
public override bool Equals(object obj)
{
if (obj == null) return false;
if (!(obj is Person)) return false;
return Equals((Person)obj);
}
public override int GetHashCode()
{
return FirstName.GetHashCode() ^ LastName.GetHashCode();
}
}
4. Использование оператора == (перегрузка)
— Можно перегрузить оператор == для сравнения объектов вашего класса.
— Важно! Перегрузка оператора == должна всегда сопровождаться перегрузкой оператора !=.
— Преимущества:
— Более удобный и интуитивный синтаксис.
public class Person
{
// ... (другие свойства и методы) ...public static bool operator ==(Person left, Person right)
{
if (ReferenceEquals(left, right))
{
return true;
}
if ((object)left == null || (object)right == null)
{
return false;
}
return left.FirstName == right.FirstName && left.LastName == right.LastName;
}
public static bool operator !=(Person left, Person right)
{
return !(left == right);
}
}
Рекомендации:
— Переопределяйте Equals(object) и GetHashCode() всегда, если вы переопределяете один из них.
— Используйте IEquatable<T>, если вы хотите обеспечить типизированное сравнение.
— Перегружайте операторы == и !=, если хотите обеспечить более удобный синтаксис.
— Внимательно продумайте, какие члены класса должны влиять на сравнение.
— Проверьте, чтобы ваши сравнения были транзитивными, симметричными и рефлексивными.
K>Главная проблема рефлекшена даже не в скорости, а в надежности. K>Если программа устроена так, что банальный рефакторинг с переименованием класса или поля может напрочь сломать логику программы — это опасно и нехорошо. Атрибуты частично решают проблему, но все равно кривовато.
хехе. с этим вообще бы там была беда. коробка собирается из кучи пакетов. набор уникальный для заказчика
SP>ну и когда добавится новое поле (н-р Surname) придётся менять все методы. Бред. Точнее в С++ как-то так и едят этот кактус, но это явно не то, к чему надо стремиться
·>и проверка соответствия шаблона "/users/:id" сигнатуре метода будет происходить в момент байндинга (т.е. запуска сервиса), а не во время работы этого метода (т.е. когда пользователь кликнет соответствующую кнопку).
с с++ дел не имел больше 20 лет.
поэтому вопрос — как обстоит дело с отладкой?
Здравствуйте, undo75, Вы писали:
U>а как и где это обходится?
можно погуглить
public static List<PropertyInfo> GetDifferences(Object test1, Object test2)
{
List<PropertyInfo> differences = new List<PropertyInfo>();
foreach (PropertyInfo property in test1.GetType().GetProperties())
{
object value1 = property.GetValue(test1, null);
object value2 = property.GetValue(test2, null);
if (!value1.Equals(value2))
{
differences.Add(property);
}
}
return differences;
}
...
public override bool Equals(object obj)
{
if (obj == null) return false;
if (GetType() != obj.GetType()) return false;
Person other = (Person)obj;
return GetDifferences(this, other).Empty();
}
Опять же, слухи ходят, что данный код будет не так шустро работать, но обычно кто программирует на шарпе, вопросами скорости интересуется слабо. Да и компилятор мог бы и оптимизировать данный код.
Здравствуйте, undo75, Вы писали:
u> ·>и проверка соответствия шаблона "/users/:id" сигнатуре метода будет происходить в момент байндинга (т.е. запуска сервиса), а не во время работы этого метода (т.е. когда пользователь кликнет соответствующую кнопку). u> с с++ дел не имел больше 20 лет. u> поэтому вопрос — как обстоит дело с отладкой?
Я не понял о каком именно из "яп с рефлексией" ты спрашиваешь. В java, например, с отладкой всё просто замечательно.
SP>Опять же, слухи ходят, что данный код будет не так шустро работать, но обычно кто программирует на шарпе, вопросами скорости интересуется слабо. Да и компилятор мог бы и оптимизировать данный код.
ну в случае рефлекшена интересоваться приходится )
u>> поэтому вопрос — как обстоит дело с отладкой? ·>Я не понял о каком именно из "яп с рефлексией" ты спрашиваешь. В java, например, с отладкой всё просто замечательно.
извини. вот у тебя динамически формируется класс. фиг знает как там на джаве, предполагаю, что как и везде. где точку останова ставить? )
Здравствуйте, undo75, Вы писали:
u> ·>Я не понял о каком именно из "яп с рефлексией" ты спрашиваешь. В java, например, с отладкой всё просто замечательно. u> извини. вот у тебя динамически формируется класс.
Причём тут рефлексия? Это кодогенерация.
u> фиг знает как там на джаве, предполагаю, что как и везде. где точку останова ставить? )
Динамически это уже после запуска приложения? В этом случае может генерироваться байткод напрямую, поэтому класса в принципе может и не быть. Впрочем, вместе с байт-кодом можно генерить дебажную инфу и отладчик это всё будет видеть.
Как более разумный вариант — есть annotation processors, в каком-то смысле плагин к компилятору, позволяющий генерировать исходный код во время компиляции, хоть с комментариями и javadoc. Тогда это всё в sources и будет доступно для IDE.
Здравствуйте, Pzz, Вы писали:
Pzz>Здравствуйте, sergii.p, Вы писали:
SP>>Можно конечно без этого. В С++ например до сих пор без рефлексии как-то обходятся. Но это просто ещё один инструмент, который иногда может улучшить код. В том же C++ находятся некоторые, которые говорят, что шаблоны не нужны. Ну да, 95% шаблоны не нужны, они их просто используют. Но знать инструмент и уметь его применять надо.
Pzz>Если делаешь сериализацию без рефлексии, приходится каждое поле структуры дважды описывать: один раз в самом описании структуры и второй раз для сериялизатора.
Pzz>А когда есть два параллельных описания одного и того же, рано или поздно они расползутся...
А при рефакторинге структур все равно надо делать совместимость.
И когда кодом пишешь это потом намного легче. И хотя у меня есть возможность пользоваться рефлексией делаю в 80% случаев делаю сериализацию отдельно.
Отдельно в файл и отдельно в REST API.
Здравствуйте, sergii.p, Вы писали:
SP>Можно конечно без этого. В С++ например до сих пор без рефлексии как-то обходятся.
Костылями, объездами на кривых козах и прочими моральными недугами обходятся.
SP>Вообще я вот считаю, что рефлексия должна быть времени компиляции. Это бы избавило от многих проблем отладки и скорости. Но Java и C# уже только могила исправит.
+ про CT reflect
SP>В том же C++ находятся некоторые, которые говорят, что шаблоны не нужны. Ну да, 95% шаблоны не нужны, они их просто используют. Но знать инструмент и уметь его применять надо.
В Java ct шаблоны и rt рефлексия.
В c++ rt шаблоны и (будет) ct рефлексия.
·>Причём тут рефлексия? Это кодогенерация.
это делается с помощью нее. в нашем случае
·>Динамически это уже после запуска приложения? В этом случае может генерироваться байткод напрямую, поэтому класса в принципе может и не быть. Впрочем, вместе с байт-кодом можно генерить дебажную инфу и отладчик это всё будет видеть.
можно, но нет )
·>Как более разумный вариант — есть annotation processors, в каком-то смысле плагин к компилятору, позволяющий генерировать исходный код во время компиляции, хоть с комментариями и javadoc. Тогда это всё в sources и будет доступно для IDE.
не делается )
Здравствуйте, undo75, Вы писали:
U>приватные методы — если есть потребность их дергать — признак плохого проектирования. U>про утиную типизацию не слышал )
Утиная типизация это аналог IDispatch, dynamic. Хорош когда есть куча свойств типа object c одинаковым набором имен свойств методов.
Для типизации надо распространять библиотеку, но проблемы могут возникать когда данная библиотека может часто изменяться и возникают проблемы с версиями.
Ну и использование в плагинах динамических языков.
Вот тут прекрасно подходят динамики работающие через рефлекшен
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, undo75, Вы писали:
P>>Вполне может оказаться так, что дело именно в том, что вы привыкли делать все по старинке.
U>посмешил ) код динамически созданный тоже внезапно работает "по старинке". только дотягиваться до него надо через задницу
Это ваше желание дотягиваться через задницу, т.к. опыта работы с рефлексией у вас нет. Покажите пример кода, где вся эта хитрая рефлексия, что бы предметно было.
Например, в AOP, orm, серилизации, di/ioc, http и прочих контролерах обычно нет необходимости дебажить — вам нужно просто запомнить основные правила.
Проблема обычно в том случае, если какой нибудь доморощеный di/ioc не покрыт тестами и следовательно содержит изрядное количество багов.
В этом случае нужно пенять не на рефлексию и ioc, а на отсутствие тестов и доморощенный механизм.
Соответсвенно, решать проблему не многодневным дебагом, а написанием тестов или заменой одного механизма на его взрослый полноценный эквивалент.
P>Это ваше желание дотягиваться через задницу, т.к. опыта работы с рефлексией у вас нет. Покажите пример кода, где вся эта хитрая рефлексия, что бы предметно было.
извини, но нет. посодют )
да и вообще даже если покажу — без контекста понятно точно не будет
Здравствуйте, undo75, Вы писали:
U>для прикладника он вообще нужен? ни одной задачи с потолка не смог придумать. U>не ну я понимаю, орм там всякие. для прикладника нафига?
Свой, более лутшый Спринг и Энтити наваять
U>в моей практике потребовалось лишь один раз. U>была библиотека и требовалось дернуть закрытый метод. без него ну вообще никак. исходников не было. и все. за 20 лет практики..
Слабовато
А как же вот это вот все: побегать по названиям пропертей / методов объектов (например ваял как-то тестраннер, который по содержимому импортов в сборках определял, в каком конкретно тестфреймворке запускать тестики), сгенерить-запулить "на лету" какой-нить код в виде пользовательского скрипта? и еще 1001 применение?
W>А как же вот это вот все: побегать по названиям пропертей / методов объектов (например ваял как-то тестраннер, который по содержимому импортов в сборках определял, в каком конкретно тестфреймворке запускать тестики), сгенерить-запулить "на лету" какой-нить код в виде пользовательского скрипта? и еще 1001 применение?
а нафиг это все, ели по большому счету нужно джейсоны туда сюда гонять, да запросы в базу писать? упрощенно если.
Здравствуйте, undo75, Вы писали:
U>а нафиг это все, ели по большому счету нужно джейсоны туда сюда гонять, да запросы в базу писать? упрощенно если.
Допустим, однако то, что в конкретно твоей кейсе рефлекшн ненужно, не означает, что ненужно вообще, в целом.
Ну не хтели предыдущие поколения следовать kiss штош теперь, весь рабочий код на свалку?
Выходит в твоем случае иллюзорно избыточно гибкая архитектура трансформируется в неиллюзорный технический долг по чистке вот этого всего, судя по твоей истории.
Здравствуйте, undo75, Вы писали: U>а нафиг это все, ели по большому счету нужно джейсоны туда сюда гонять, да запросы в базу писать? упрощенно если.
Ну так это и есть каноническая область применения рефлекшна. Любая сериализация/десериализация джейсона в строгий тип требует информации о том, как свойства класса раскладываются на атрибуты и коллекции.
Если нет строгого типа — то нужно полное покрытие тестами, иначе любое мелкое изменение в API приводит к отложенным 500 Internal Error: null reference exception.
А для запросов в базу безусловный непревзойдённый лидер — это https://github.com/linq2db/linq2db. А там под капотом — сплошной рефлекшн, причём не только на чтение, но и на запись (с порождением кода в рантайме).
Но, повторюсь, прикладнику всё это напрямую не видно. У него в коде вообще не должно быть строки вида using System.Reflection.
Просто работает магия вида
var q =
from p in DB.Products
where p.Category == category
orderby p.Rating descending
select p;
if (maxPrice.HasValue)
q = from p in q where p.Price <= maxPrice.Value;
var d = q.ToList();
return JsonSerializer.Serialize(new {Count = q.Count; Items = d});
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, undo75, Вы писали:
U>для прикладника он вообще нужен? ни одной задачи с потолка не смог придумать. U>не ну я понимаю, орм там всякие. для прикладника нафига? U>в своей практике применял, только когда изучал
U>п.с. навеяно текущим местом работы, где на нем вообще все ) из-за этого отладка сильно затруднена.... ничего сложного, но все через жопу делается и занимает кучу времени. имхо выбор был мягко говоря не обоснован. видимо на истоках был юноша со взглядом горящим, который про это прочитал и его кто-то послушал. и панеслась... других предположений у меня нет
U>в моей практике потребовалось лишь один раз. U>была библиотека и требовалось дернуть закрытый метод. без него ну вообще никак. исходников не было. и все. за 20 лет практики..
Использовал один раз для написания своей библиотеки для доступа к бд. В принципе рефлексия для подобных простых, рутинных операций и где нужно отобразить одно в другое или соединить как-то одно с другим. Основной недостаток ее это то, что тип является частью контракта, например у нас может быть функция использующая рефлексию для которой нужно что бы все свойства входного объекта были публичными. В коде это ни где не прописывается, мы не можем описать некий метакласс классы которого имеют только публичные свойства и потому надежды на компилятор нет.