для прикладника он вообще нужен? ни одной задачи с потолка не смог придумать.
не ну я понимаю, орм там всякие. для прикладника нафига?
в своей практике применял, только когда изучал
п.с. навеяно текущим местом работы, где на нем вообще все ) из-за этого отладка сильно затруднена.... ничего сложного, но все через жопу делается и занимает кучу времени. имхо выбор был мягко говоря не обоснован. видимо на истоках был юноша со взглядом горящим, который про это прочитал и его кто-то послушал. и панеслась... других предположений у меня нет
в моей практике потребовалось лишь один раз.
была библиотека и требовалось дернуть закрытый метод. без него ну вообще никак. исходников не было. и все. за 20 лет практики..
Здравствуйте, undo75, Вы писали:
U>для прикладника он вообще нужен? ни одной задачи с потолка не смог придумать. U>не ну я понимаю, орм там всякие. для прикладника нафига?
(де-)сериализация, инструменты для отладки. Больше ничего в голову не приходит.
_____________________
С уважением,
Stanislav V. Zudin
U>в моей практике потребовалось лишь один раз. U>была библиотека и требовалось дернуть закрытый метод. без него ну вообще никак. исходников не было. и все. за 20 лет практики..
я так понимаю, вопрос в контексте .NET.
Из вынужденных хаков:
1) работа с приватными методами сторонней библиотеки
2) использовать библиотеку из .net большей версии в проекте меньшей версии
В остальном: (де)сериализация.
Что-то ещё по мелочи..
Здравствуйте, undo75, Вы писали:
U>для прикладника он вообще нужен? ни одной задачи с потолка не смог придумать. U>не ну я понимаю, орм там всякие. для прикладника нафига?
Думаю нет, для прикладного программирования не нужно.
Прикладного в том смысле, что программист пишет программу для не-программистов.
Я видел разумное использование только в контексте "от программистов для дугих программистов",
т.е. библиотеки по сути, или инструменты какие-нибудь, типа кастомные аттрибуты, шаблоны, кодогенераторы.
ну если в двух словах и к месту и ни к месту. вообще везде. идея у них в кастомизации коробки. это в двух словах. причем кастомизации не только для пользователей, но и для программистов. написана масса шаблонизаторов на все случаи жизни ) почему визард в студии не написали тогда — для меня загадка. только консоль. только хардкор...
bnk>Я видел разумное использование только в контексте "от программистов для дугих программистов", bnk>т.е. библиотеки по сути, или инструменты какие-нибудь, типа кастомные аттрибуты, шаблоны, кодогенераторы.
это тоже считаю не обоснованным. к примеру в одном из мест был написан инструмент, делающий настройки для различных объектов. хранились в базе. и уверен на 100% что такое решение куда быстрее рефлекшена. а для отладки гораздо прозрачнее..
U>это тоже считаю не обоснованным. к примеру в одном из мест был написан инструмент, делающий настройки для различных объектов. хранились в базе. и уверен на 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>Если программа устроена так, что банальный рефакторинг с переименованием класса или поля может напрочь сломать логику программы — это опасно и нехорошо. Атрибуты частично решают проблему, но все равно кривовато.
хехе. с этим вообще бы там была беда. коробка собирается из кучи пакетов. набор уникальный для заказчика
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) придётся менять все методы. Бред. Точнее в С++ как-то так и едят этот кактус, но это явно не то, к чему надо стремиться
SP>ну и когда добавится новое поле (н-р Surname) придётся менять все методы. Бред. Точнее в С++ как-то так и едят этот кактус, но это явно не то, к чему надо стремиться
Здравствуйте, 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" сигнатуре метода будет происходить в момент байндинга (т.е. запуска сервиса), а не во время работы этого метода (т.е. когда пользователь кликнет соответствующую кнопку).
·>и проверка соответствия шаблона "/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, например, с отладкой всё просто замечательно.
извини. вот у тебя динамически формируется класс. фиг знает как там на джаве, предполагаю, что как и везде. где точку останова ставить? )