рефлекшен
От: undo75  
Дата: 29.08.24 12:32
Оценка:
для прикладника он вообще нужен? ни одной задачи с потолка не смог придумать.
не ну я понимаю, орм там всякие. для прикладника нафига?
в своей практике применял, только когда изучал

п.с. навеяно текущим местом работы, где на нем вообще все ) из-за этого отладка сильно затруднена.... ничего сложного, но все через жопу делается и занимает кучу времени. имхо выбор был мягко говоря не обоснован. видимо на истоках был юноша со взглядом горящим, который про это прочитал и его кто-то послушал. и панеслась... других предположений у меня нет

в моей практике потребовалось лишь один раз.
была библиотека и требовалось дернуть закрытый метод. без него ну вообще никак. исходников не было. и все. за 20 лет практики..
Отредактировано 29.08.2024 12:42 undo75 . Предыдущая версия .
Re: рефлекшен
От: Stanislav V. Zudin Россия  
Дата: 29.08.24 12:41
Оценка:
Здравствуйте, undo75, Вы писали:

U>для прикладника он вообще нужен? ни одной задачи с потолка не смог придумать.

U>не ну я понимаю, орм там всякие. для прикладника нафига?

(де-)сериализация, инструменты для отладки. Больше ничего в голову не приходит.
_____________________
С уважением,
Stanislav V. Zudin
Re: рефлекшен
От: m2user  
Дата: 29.08.24 12:57
Оценка:
U>в моей практике потребовалось лишь один раз.
U>была библиотека и требовалось дернуть закрытый метод. без него ну вообще никак. исходников не было. и все. за 20 лет практики..

я так понимаю, вопрос в контексте .NET.
Из вынужденных хаков:
1) работа с приватными методами сторонней библиотеки
2) использовать библиотеку из .net большей версии в проекте меньшей версии

В остальном: (де)сериализация.
Что-то ещё по мелочи..

А как в твоем проекте рефлексия используется?
Отредактировано 29.08.2024 13:43 m2user . Предыдущая версия .
Re: рефлекшен
От: bnk СССР http://unmanagedvisio.com/
Дата: 29.08.24 13:21
Оценка:
Здравствуйте, undo75, Вы писали:

U>для прикладника он вообще нужен? ни одной задачи с потолка не смог придумать.

U>не ну я понимаю, орм там всякие. для прикладника нафига?

Думаю нет, для прикладного программирования не нужно.
Прикладного в том смысле, что программист пишет программу для не-программистов.

Я видел разумное использование только в контексте "от программистов для дугих программистов",
т.е. библиотеки по сути, или инструменты какие-нибудь, типа кастомные аттрибуты, шаблоны, кодогенераторы.
Re[2]: рефлекшен
От: undo75  
Дата: 29.08.24 13:26
Оценка:
M>А как в твоем проекте рефлексия используется?

ну если в двух словах и к месту и ни к месту. вообще везде. идея у них в кастомизации коробки. это в двух словах. причем кастомизации не только для пользователей, но и для программистов. написана масса шаблонизаторов на все случаи жизни ) почему визард в студии не написали тогда — для меня загадка. только консоль. только хардкор...
Re[2]: рефлекшен
От: undo75  
Дата: 29.08.24 13:28
Оценка:
bnk>Я видел разумное использование только в контексте "от программистов для дугих программистов",
bnk>т.е. библиотеки по сути, или инструменты какие-нибудь, типа кастомные аттрибуты, шаблоны, кодогенераторы.

это тоже считаю не обоснованным. к примеру в одном из мест был написан инструмент, делающий настройки для различных объектов. хранились в базе. и уверен на 100% что такое решение куда быстрее рефлекшена. а для отладки гораздо прозрачнее..
Re[3]: рефлекшен
От: klopodav  
Дата: 29.08.24 14:03
Оценка: +1
U>это тоже считаю не обоснованным. к примеру в одном из мест был написан инструмент, делающий настройки для различных объектов. хранились в базе. и уверен на 100% что такое решение куда быстрее рефлекшена. а для отладки гораздо прозрачнее..

Главная проблема рефлекшена даже не в скорости, а в надежности.
Если программа устроена так, что банальный рефакторинг с переименованием класса или поля может напрочь сломать логику программы — это опасно и нехорошо. Атрибуты частично решают проблему, но все равно кривовато.
Re: рефлекшен
От: Alekzander  
Дата: 29.08.24 14:08
Оценка: +1
Здравствуйте, undo75, Вы писали:

U>для прикладника он вообще нужен? ни одной задачи с потолка не смог придумать.


Object Inspector / Properties.
I'm a sewer mutant, and my favorite authors are Edgar Allan Poo, H.G. Smells and George R.R. Martin.
Re: рефлекшен
От: sergii.p  
Дата: 29.08.24 18:26
Оценка:
Здравствуйте, undo75, Вы писали:

U>в моей практике потребовалось лишь один раз.

U>была библиотека и требовалось дернуть закрытый метод. без него ну вообще никак. исходников не было. и все. за 20 лет практики..

я использовал в логировании. Вроде по факту задача сериализации. Но несколько хитрее. И сохранение в файл. Когда у вас самописный формат и всякие JsonSerializer не подходят.
Можно конечно без этого. В С++ например до сих пор без рефлексии как-то обходятся. Но это просто ещё один инструмент, который иногда может улучшить код. В том же C++ находятся некоторые, которые говорят, что шаблоны не нужны. Ну да, 95% шаблоны не нужны, они их просто используют. Но знать инструмент и уметь его применять надо.
Я вот не знаю, как в С# принято делать метод Equals? Ручками писать все поля? Ведь так и ошибиться можно. А с рефлексией это всё делается в пару строчек и намного безопаснее. Ну может немного больше писать, если заморочиться на скорости.
Вообще я вот считаю, что рефлексия должна быть времени компиляции. Это бы избавило от многих проблем отладки и скорости. Но Java и C# уже только могила исправит.
Re[2]: рефлекшен
От: undo75  
Дата: 29.08.24 19:39
Оценка:
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>, если вы хотите обеспечить типизированное сравнение.
— Перегружайте операторы == и !=, если хотите обеспечить более удобный синтаксис.
— Внимательно продумайте, какие члены класса должны влиять на сравнение.
— Проверьте, чтобы ваши сравнения были транзитивными, симметричными и рефлексивными.

Re[4]: рефлекшен
От: undo75  
Дата: 30.08.24 04:35
Оценка:
K>Главная проблема рефлекшена даже не в скорости, а в надежности.
K>Если программа устроена так, что банальный рефакторинг с переименованием класса или поля может напрочь сломать логику программы — это опасно и нехорошо. Атрибуты частично решают проблему, но все равно кривовато.

хехе. с этим вообще бы там была беда. коробка собирается из кучи пакетов. набор уникальный для заказчика
Re[3]: рефлекшен
От: sergii.p  
Дата: 30.08.24 08:56
Оценка: +1
Здравствуйте, undo75, Вы писали:

U>как-то так

U>

U>

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) придётся менять все методы. Бред. Точнее в С++ как-то так и едят этот кактус, но это явно не то, к чему надо стремиться
Re[4]: рефлекшен
От: undo75  
Дата: 30.08.24 10:03
Оценка:
SP>ну и когда добавится новое поле (н-р Surname) придётся менять все методы. Бред. Точнее в С++ как-то так и едят этот кактус, но это явно не то, к чему надо стремиться

а как и где это обходится?
Re: рефлекшен
От: · Великобритания  
Дата: 30.08.24 11:05
Оценка: 5 (1) +2
Здравствуйте, 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" сигнатуре метода будет происходить в момент байндинга (т.е. запуска сервиса), а не во время работы этого метода (т.е. когда пользователь кликнет соответствующую кнопку).
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[2]: рефлекшен
От: undo75  
Дата: 30.08.24 12:05
Оценка:
·>и проверка соответствия шаблона "/users/:id" сигнатуре метода будет происходить в момент байндинга (т.е. запуска сервиса), а не во время работы этого метода (т.е. когда пользователь кликнет соответствующую кнопку).
с с++ дел не имел больше 20 лет.
поэтому вопрос — как обстоит дело с отладкой?
Re[5]: рефлекшен
От: sergii.p  
Дата: 30.08.24 12:15
Оценка:
Здравствуйте, 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();
}


Опять же, слухи ходят, что данный код будет не так шустро работать, но обычно кто программирует на шарпе, вопросами скорости интересуется слабо. Да и компилятор мог бы и оптимизировать данный код.
Re[3]: рефлекшен
От: · Великобритания  
Дата: 30.08.24 12:30
Оценка:
Здравствуйте, undo75, Вы писали:

u> ·>и проверка соответствия шаблона "/users/:id" сигнатуре метода будет происходить в момент байндинга (т.е. запуска сервиса), а не во время работы этого метода (т.е. когда пользователь кликнет соответствующую кнопку).

u> с с++ дел не имел больше 20 лет.
u> поэтому вопрос — как обстоит дело с отладкой?
Я не понял о каком именно из "яп с рефлексией" ты спрашиваешь. В java, например, с отладкой всё просто замечательно.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 30.08.2024 12:30 · . Предыдущая версия .
Re[6]: рефлекшен
От: undo75  
Дата: 30.08.24 13:26
Оценка:
SP>Опять же, слухи ходят, что данный код будет не так шустро работать, но обычно кто программирует на шарпе, вопросами скорости интересуется слабо. Да и компилятор мог бы и оптимизировать данный код.

ну в случае рефлекшена интересоваться приходится )
Re[4]: рефлекшен
От: undo75  
Дата: 30.08.24 13:27
Оценка:
u>> поэтому вопрос — как обстоит дело с отладкой?
·>Я не понял о каком именно из "яп с рефлексией" ты спрашиваешь. В java, например, с отладкой всё просто замечательно.

извини. вот у тебя динамически формируется класс. фиг знает как там на джаве, предполагаю, что как и везде. где точку останова ставить? )
Re[5]: рефлекшен
От: GarryIV  
Дата: 30.08.24 13:38
Оценка: +3
Здравствуйте, undo75, Вы писали:

U>извини. вот у тебя динамически формируется класс.

рефлекшен != "динамически формируется класс". рефлекшн это посмотреть уже готовые классы
генерация [байт]кода отдельная тема.
WBR, Igor Evgrafov
Re[2]: рефлекшен
От: Pzz Россия https://github.com/alexpevzner
Дата: 30.08.24 14:05
Оценка: +1
Здравствуйте, sergii.p, Вы писали:

SP>Можно конечно без этого. В С++ например до сих пор без рефлексии как-то обходятся. Но это просто ещё один инструмент, который иногда может улучшить код. В том же C++ находятся некоторые, которые говорят, что шаблоны не нужны. Ну да, 95% шаблоны не нужны, они их просто используют. Но знать инструмент и уметь его применять надо.


Если делаешь сериализацию без рефлексии, приходится каждое поле структуры дважды описывать: один раз в самом описании структуры и второй раз для сериялизатора.

А когда есть два параллельных описания одного и того же, рано или поздно они расползутся...
Re[6]: рефлекшен
От: undo75  
Дата: 30.08.24 14:27
Оценка:
GIV>рефлекшен != "динамически формируется класс". рефлекшн это посмотреть уже готовые классы
GIV>генерация [байт]кода отдельная тема.

ну тут именно до такой степени запущено все

помню на собеседовании сосредоточено было внимание что он может не только созаваться, но и удаляться )

для них это в общем важно )
Отредактировано 30.08.2024 14:30 undo75 . Предыдущая версия . Еще …
Отредактировано 30.08.2024 14:29 undo75 . Предыдущая версия .
Re[5]: рефлекшен
От: · Великобритания  
Дата: 30.08.24 15:37
Оценка:
Здравствуйте, undo75, Вы писали:

u> ·>Я не понял о каком именно из "яп с рефлексией" ты спрашиваешь. В java, например, с отладкой всё просто замечательно.

u> извини. вот у тебя динамически формируется класс.
Причём тут рефлексия? Это кодогенерация.

u> фиг знает как там на джаве, предполагаю, что как и везде. где точку останова ставить? )

Динамически это уже после запуска приложения? В этом случае может генерироваться байткод напрямую, поэтому класса в принципе может и не быть. Впрочем, вместе с байт-кодом можно генерить дебажную инфу и отладчик это всё будет видеть.

Как более разумный вариант — есть annotation processors, в каком-то смысле плагин к компилятору, позволяющий генерировать исходный код во время компиляции, хоть с комментариями и javadoc. Тогда это всё в sources и будет доступно для IDE.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[3]: рефлекшен
От: swame  
Дата: 30.08.24 17:36
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, sergii.p, Вы писали:


SP>>Можно конечно без этого. В С++ например до сих пор без рефлексии как-то обходятся. Но это просто ещё один инструмент, который иногда может улучшить код. В том же C++ находятся некоторые, которые говорят, что шаблоны не нужны. Ну да, 95% шаблоны не нужны, они их просто используют. Но знать инструмент и уметь его применять надо.


Pzz>Если делаешь сериализацию без рефлексии, приходится каждое поле структуры дважды описывать: один раз в самом описании структуры и второй раз для сериялизатора.


Pzz>А когда есть два параллельных описания одного и того же, рано или поздно они расползутся...


А при рефакторинге структур все равно надо делать совместимость.
И когда кодом пишешь это потом намного легче. И хотя у меня есть возможность пользоваться рефлексией делаю в 80% случаев делаю сериализацию отдельно.
Отдельно в файл и отдельно в REST API.
Re: рефлекшен
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 30.08.24 18:32
Оценка:
Здравствуйте, undo75, Вы писали:

Например PropertyGrid
А так универсальные сериализаторы, десериализаторы. Хотя сейчас с приходом Source Generator и Native AOT надобность в них снижается
Универсальный маршалинг .Net Core, AppDomain, WCF, RPC маршалинг по Tcp/Ip свой велосипед

Приватные методы, плагины с утиной типизацией
и солнце б утром не вставало, когда бы не было меня
Re: рефлекшен
От: kov_serg Россия  
Дата: 30.08.24 19:37
Оценка: 1 (1)
Здравствуйте, undo75, Вы писали:

U>для прикладника он вообще нужен? ни одной задачи с потолка не смог придумать.

U>не ну я понимаю, орм там всякие. для прикладника нафига?

Re[2]: рефлекшен
От: andrey.desman  
Дата: 30.08.24 20:45
Оценка:
Здравствуйте, sergii.p, Вы писали:

SP>Можно конечно без этого. В С++ например до сих пор без рефлексии как-то обходятся.


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

SP>Вообще я вот считаю, что рефлексия должна быть времени компиляции. Это бы избавило от многих проблем отладки и скорости. Но Java и C# уже только могила исправит.


+ про CT reflect

SP>В том же C++ находятся некоторые, которые говорят, что шаблоны не нужны. Ну да, 95% шаблоны не нужны, они их просто используют. Но знать инструмент и уметь его применять надо.


В Java ct шаблоны и rt рефлексия.
В c++ rt шаблоны и (будет) ct рефлексия.

Я за плюсы.
Re[6]: рефлекшен
От: undo75  
Дата: 01.09.24 04:28
Оценка:
·>Причём тут рефлексия? Это кодогенерация.
это делается с помощью нее. в нашем случае

·>Динамически это уже после запуска приложения? В этом случае может генерироваться байткод напрямую, поэтому класса в принципе может и не быть. Впрочем, вместе с байт-кодом можно генерить дебажную инфу и отладчик это всё будет видеть.

можно, но нет )

·>Как более разумный вариант — есть annotation processors, в каком-то смысле плагин к компилятору, позволяющий генерировать исходный код во время компиляции, хоть с комментариями и javadoc. Тогда это всё в sources и будет доступно для IDE.

не делается )
Re[2]: рефлекшен
От: undo75  
Дата: 01.09.24 04:32
Оценка:
S>Например PropertyGrid
S> А так универсальные сериализаторы, десериализаторы. Хотя сейчас с приходом Source Generator и Native AOT надобность в них снижается
S>Универсальный маршалинг .Net Core, AppDomain, WCF, RPC маршалинг по Tcp/Ip свой велосипед

ну я отметил, что говорю про прикладные задачи.

S> Приватные методы, плагины с утиной типизацией


приватные методы — если есть потребность их дергать — признак плохого проектирования.
про утиную типизацию не слышал )
Re: рефлекшен
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 01.09.24 08:26
Оценка: +1
Здравствуйте, undo75, Вы писали:

U>п.с. навеяно текущим местом работы, где на нем вообще все ) из-за этого отладка сильно затруднена.... ничего сложного, но все через жопу делается и занимает кучу времени. имхо выбор был мягко говоря не обоснован. видимо на истоках был юноша со взглядом горящим, который про это прочитал и его кто-то послушал. и панеслась... других предположений у меня нет

U>в моей практике потребовалось лишь один раз.

А что, прикладной код не надо структурировать, не надо управлять сложностью? С другими компонентами не нало интегрироваться, не надо инструментировать свой код для логирования, отладки, мониторинга,перформанса итд?
Рефлексия это еще один иструмент, позволяет отделять мух от котлет.

Вам прежде всего тяжело, потому что вы прошли мимо этой темы.

Так часто бывает — один навесит атрибут, а другой пытается отладчиком постичь это намерение. Так не работает.

Если у вас кругом рефлексия, то нужно не отладчиком работать, а выяснять логику этой всей рефлексии, какие аспекты она применяет.

Вполне может оказаться так, что дело именно в том, что вы привыкли делать все по старинке.
Re[2]: рефлекшен
От: undo75  
Дата: 01.09.24 09:15
Оценка:
P>Вполне может оказаться так, что дело именно в том, что вы привыкли делать все по старинке.

посмешил ) код динамически созданный тоже внезапно работает "по старинке". только дотягиваться до него надо через задницу
Re[3]: рефлекшен
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 01.09.24 10:53
Оценка:
Здравствуйте, undo75, Вы писали:

U>приватные методы — если есть потребность их дергать — признак плохого проектирования.

U>про утиную типизацию не слышал )

Утиная типизация

Утиная типизация это аналог IDispatch, dynamic. Хорош когда есть куча свойств типа object c одинаковым набором имен свойств методов.
Для типизации надо распространять библиотеку, но проблемы могут возникать когда данная библиотека может часто изменяться и возникают проблемы с версиями.
Ну и использование в плагинах динамических языков.
Вот тут прекрасно подходят динамики работающие через рефлекшен
и солнце б утром не вставало, когда бы не было меня
Отредактировано 01.09.2024 11:24 Serginio1 . Предыдущая версия .
Re[3]: рефлекшен
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 01.09.24 12:07
Оценка:
Здравствуйте, undo75, Вы писали:

P>>Вполне может оказаться так, что дело именно в том, что вы привыкли делать все по старинке.


U>посмешил ) код динамически созданный тоже внезапно работает "по старинке". только дотягиваться до него надо через задницу


Это ваше желание дотягиваться через задницу, т.к. опыта работы с рефлексией у вас нет. Покажите пример кода, где вся эта хитрая рефлексия, что бы предметно было.

Например, в AOP, orm, серилизации, di/ioc, http и прочих контролерах обычно нет необходимости дебажить — вам нужно просто запомнить основные правила.

Проблема обычно в том случае, если какой нибудь доморощеный di/ioc не покрыт тестами и следовательно содержит изрядное количество багов.
В этом случае нужно пенять не на рефлексию и ioc, а на отсутствие тестов и доморощенный механизм.
Соответсвенно, решать проблему не многодневным дебагом, а написанием тестов или заменой одного механизма на его взрослый полноценный эквивалент.
Re[5]: рефлекшен
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 01.09.24 12:12
Оценка: +1
Здравствуйте, undo75, Вы писали:

u>>> поэтому вопрос — как обстоит дело с отладкой?

U>·>Я не понял о каком именно из "яп с рефлексией" ты спрашиваешь. В java, например, с отладкой всё просто замечательно.

U>извини. вот у тебя динамически формируется класс. фиг знает как там на джаве, предполагаю, что как и везде. где точку останова ставить? )


Похоже под рефлексией вы называете system.reflection куда в дотнете понапихали чуть не все подряд

Расскажите, какая задача решается кодогенерацией?

Вам достаточно переделать кодогенератор таким образом, что бы вместо простыней генерировал вызов утилиты. Эту утилиту можно покрыть тестами, и в неё вы можете поставить точку останова. Т.е. минимальные изменения, достаточно безопасные.
Re[4]: рефлекшен
От: undo75  
Дата: 01.09.24 15:30
Оценка:
P>Это ваше желание дотягиваться через задницу, т.к. опыта работы с рефлексией у вас нет. Покажите пример кода, где вся эта хитрая рефлексия, что бы предметно было.
извини, но нет. посодют )
да и вообще даже если покажу — без контекста понятно точно не будет
Re[5]: рефлекшен
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 01.09.24 19:28
Оценка:
Здравствуйте, undo75, Вы писали:

U>да и вообще даже если покажу — без контекста понятно точно не будет


И что же обсуждать без конкретики?
Re: Как зачем?
От: Wolverrum Ниоткуда  
Дата: 02.09.24 00:56
Оценка:
Здравствуйте, undo75, Вы писали:

U>для прикладника он вообще нужен? ни одной задачи с потолка не смог придумать.

U>не ну я понимаю, орм там всякие. для прикладника нафига?
Свой, более лутшый Спринг и Энтити наваять


U>в моей практике потребовалось лишь один раз.

U>была библиотека и требовалось дернуть закрытый метод. без него ну вообще никак. исходников не было. и все. за 20 лет практики..
Слабовато

А как же вот это вот все: побегать по названиям пропертей / методов объектов (например ваял как-то тестраннер, который по содержимому импортов в сборках определял, в каком конкретно тестфреймворке запускать тестики), сгенерить-запулить "на лету" какой-нить код в виде пользовательского скрипта? и еще 1001 применение?
Re[2]: Как зачем?
От: undo75  
Дата: 02.09.24 04:00
Оценка:
W>А как же вот это вот все: побегать по названиям пропертей / методов объектов (например ваял как-то тестраннер, который по содержимому импортов в сборках определял, в каком конкретно тестфреймворке запускать тестики), сгенерить-запулить "на лету" какой-нить код в виде пользовательского скрипта? и еще 1001 применение?

а нафиг это все, ели по большому счету нужно джейсоны туда сюда гонять, да запросы в базу писать? упрощенно если.
Re[6]: рефлекшен
От: m2user  
Дата: 02.09.24 07:43
Оценка:
SP>но обычно кто программирует на шарпе, вопросами скорости интересуется слабо.

угу, и профилировщиков для .NET не бывает.
Re[2]: рефлекшен
От: Alekzander  
Дата: 02.09.24 08:34
Оценка:
Здравствуйте, Alekzander, Вы писали:

U>>для прикладника он вообще нужен? ни одной задачи с потолка не смог придумать.


A>Object Inspector / Properties.


Но я всё-таки думаю, это грязный хак. Сегодня я бы не стал так проектировать, а вынес все данные во внешние схемы и байндил.
I'm a sewer mutant, and my favorite authors are Edgar Allan Poo, H.G. Smells and George R.R. Martin.
Re[6]: рефлекшен
От: undo75  
Дата: 02.09.24 08:42
Оценка:
P>И что же обсуждать без конкретики?

дак просто есть куча других путей для решения задач. зачем усложнять все? причем вообще все.
Re[3]: Как зачем?
От: Wolverrum Ниоткуда  
Дата: 02.09.24 10:38
Оценка:
Здравствуйте, undo75, Вы писали:

U>а нафиг это все, ели по большому счету нужно джейсоны туда сюда гонять, да запросы в базу писать? упрощенно если.

Допустим, однако то, что в конкретно твоей кейсе рефлекшн ненужно, не означает, что ненужно вообще, в целом.
Ну не хтели предыдущие поколения следовать kiss штош теперь, весь рабочий код на свалку?
Выходит в твоем случае иллюзорно избыточно гибкая архитектура трансформируется в неиллюзорный технический долг по чистке вот этого всего, судя по твоей истории.
Отредактировано 02.09.2024 10:39 Wolverrum . Предыдущая версия .
Re[7]: рефлекшен
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 02.09.24 13:40
Оценка: +1
Здравствуйте, undo75, Вы писали:

U>дак просто есть куча других путей для решения задач. зачем усложнять все? причем вообще все.


Без конкретики — ничего не ясно. вы даже не ответили, с чем именно проблема, с рефлексией или с кодогенерацией.

Усложнять можно вообще везде где угодно, с любым подходом. У каждого инструмента есть границы применимости.
Если вы инструментами не владеете, то подозреваю, проделываете раз в 100 больше лишней работы.
Это все ровно ничего не говорит о том, что так или не так с вашим проектом

И у рефлексии, и у кодогенерации есть бенефиты — сокращают количество рукописного кода в десятки раз.

Если у вас на проекте чтото не так пошло, варианты
1. вы не умеете этим пользоваться — с ваших слов, у вас нет опыта
2. товарищ, который писал, не умел этим пользоваться — ваше предположение
3. цели, масштабы проекта изменились

Вобщем, кроме ваших эмоций здесь обсуждать нечего
Re[3]: Как зачем?
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 02.09.24 13:46
Оценка: +2
Здравствуйте, undo75, Вы писали:

W>>А как же вот это вот все: побегать по названиям пропертей / методов объектов (например ваял как-то тестраннер, который по содержимому импортов в сборках определял, в каком конкретно тестфреймворке запускать тестики), сгенерить-запулить "на лету" какой-нить код в виде пользовательского скрипта? и еще 1001 применение?


U>а нафиг это все, ели по большому счету нужно джейсоны туда сюда гонять, да запросы в базу писать? упрощенно если.


Потому и нужно. Например, если у вас хрен-знает-сколькилион таких методов, с тз разработки проще сделать это именно через метапрограммирование
Вместо выписывания тысяч методов, и тестирования! вам нужен один конфиг/дсл/скрипт/итд.

можно пойти иначе — выписывать все по кусочку. Только вот стоимость разработки и поддержки на мой взгляд ну не очень.

Единственное, на что можно сетовать — кодогенерация это интрузивная вещь, избавиться от неё довольно трудно, в отличие от обычного дублирующегося кода.
Re: рефлекшен
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.09.24 03:27
Оценка: +1
Здравствуйте, 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 про сериализацию - только прикладная логика, уникальная для этого класса.
}



* пример умозрительный, иллюстративный. Я знаю, что конкретно на этом языке можно решить эту задачу и без рефлекшна, и без прямой императивщины в прикладном коде.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: рефлекшен
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.09.24 03:33
Оценка: 3 (1)
Здравствуйте, undo75, Вы писали:


SP>>ну и когда добавится новое поле (н-р Surname) придётся менять все методы. Бред. Точнее в С++ как-то так и едят этот кактус, но это явно не то, к чему надо стремиться


U>а как и где это обходится?

Если известно, что класс описывает "плоские" объекты, в которых свойства соответствуют хранимым атрибутам (а не рантайм-состоянию со сложной эволюцией), то его можно сконструировать гораздо компактнее:
public record Person(string FirstName, string LastName);

Это приведёт не только к объявлению свойств FirstName и LastName и публичного конструктора с одноименными аргументами, но и к автоматическому порождению метода Equals, который будет устроен примерно так, как вы показывали.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Как зачем?
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.09.24 03:41
Оценка: 1 (1)
Здравствуйте, Wolverrum, Вы писали:
W>Свой, более лутшый Спринг и Энтити наваять
Это уже не прикладник. Это платформист.
Платформисту рефлексия — лучший друг, товарищ и брат. Также, как шаблоны, перегрузки операторов и функций, функции высшего порядка, и прочие сантехнические инструменты.

А прикладник — он кнопку нажал, говно смылось. Всё.

P.S. Один мой коллега построил себе дом, завёл систему умного дома. Смеялся над типичными внедряльщиками таких систем. "Они спрашивают: сколько у вас будет сценариев освещения?"
Ему очевидно, что основных "сценариев" для любого освещения всего два: "сделай поярче" и "сделай потемнее". А вот эти все "просмотр кино"/"видеозвонок другу"/"семейный ужин от 2х до 4х человек" — наркомания, которой невозможно пользоваться. Точно так же, как приборной панелью с 38 кнопками типа "нижняя подсветка в винном шкафу" и "софиты юго-запад".

Всё, что мы пилим — это способы борьбы со сложностью. Все несущественные подробности нужно убирать с глаз долой.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: Как зачем?
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.09.24 04:37
Оценка:
Здравствуйте, 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});
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: рефлекшен
От: flаt  
Дата: 03.09.24 04:55
Оценка: :)
Здравствуйте, undo75, Вы писали:


Кстати, а почему не сделать просто:

U>
U>    public override bool Equals(object obj)
U>    {
U>        return this.GetHashCode() == obj.GetHashCode();
U>    }

U>



А уже в `GetHashCode()` перечислять все поля — на один метод меньше обновлять, если класс меняется.
Re: рефлекшен
От: Qulac Россия  
Дата: 03.09.24 06:21
Оценка:
Здравствуйте, undo75, Вы писали:

U>для прикладника он вообще нужен? ни одной задачи с потолка не смог придумать.

U>не ну я понимаю, орм там всякие. для прикладника нафига?
U>в своей практике применял, только когда изучал

U>п.с. навеяно текущим местом работы, где на нем вообще все ) из-за этого отладка сильно затруднена.... ничего сложного, но все через жопу делается и занимает кучу времени. имхо выбор был мягко говоря не обоснован. видимо на истоках был юноша со взглядом горящим, который про это прочитал и его кто-то послушал. и панеслась... других предположений у меня нет


U>в моей практике потребовалось лишь один раз.

U>была библиотека и требовалось дернуть закрытый метод. без него ну вообще никак. исходников не было. и все. за 20 лет практики..

Использовал один раз для написания своей библиотеки для доступа к бд. В принципе рефлексия для подобных простых, рутинных операций и где нужно отобразить одно в другое или соединить как-то одно с другим. Основной недостаток ее это то, что тип является частью контракта, например у нас может быть функция использующая рефлексию для которой нужно что бы все свойства входного объекта были публичными. В коде это ни где не прописывается, мы не можем описать некий метакласс классы которого имеют только публичные свойства и потому надежды на компилятор нет.
Программа – это мысли спрессованные в код
Re[4]: рефлекшен
От: sergii.p  
Дата: 03.09.24 08:10
Оценка: +1
Здравствуйте, flаt, Вы писали:

F>А уже в `GetHashCode()` перечислять все поля — на один метод меньше обновлять, если класс меняется.


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