|
Универсальный setter
|
|||
---|---|---|---|
#18+
Дело опять касается boilerplate реализаций INotifyPropertyChanged и свойств. Как вам такое решение (нашёл в Интернете)? Какие плюсы и минусы вы видите? Есть вообще смысл так делать - "униваресальные свойства" и т. п.? Тут, значит, штука в том, что есть универсальный сеттер и эта новая штука - атрибут CallerMemberName. Плюс в том, что нет жёстко заданных строк в имени propertyName, нет медленной рефлексии, нет выражений - всё это требовалось в разных реализациях, уводящих от жёстко заданных строк. Если только реализация CallerMemberName сама по себе не медленная, то всё вообще замечательно. Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35.
... |
|||
:
Нравится:
Не нравится:
|
|||
19.01.2014, 16:17 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
Хотя в Постшарпе выглядит лучше ... ... |
|||
:
Нравится:
Не нравится:
|
|||
19.01.2014, 16:17 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
Да-да... уличная магия... user7320Хотя в Постшарпе... Хм... уличная магия... user7320нашёл в Интернете... нет медленной рефлексии... Ну а вообще, в данном случае, домотканный код... лично мне симпатичнее непрозрачного посташрпа :) Хоть там оно и выглядит лучше :) ... |
|||
:
Нравится:
Не нравится:
|
|||
19.01.2014, 17:31 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320Есть вообще смысл так делать - "универсальные свойства" и т. п.? Я считаю, что нет. Подумайте о тех, кто будет поддерживать. Поставит кто-нибудь брейкпойнт в этом свойстве - и будет 30 раз тыкать, пока нужное пройдет. Сейчас я такими вот вещами занимаюсь. Наабстрагировали и науниверсилизировали настолько, что на перемещение иконки на 20 пикселей дают 4 дня. И почти хватает! ... |
|||
:
Нравится:
Не нравится:
|
|||
19.01.2014, 18:18 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
D129user7320Есть вообще смысл так делать - "универсальные свойства" и т. п.? Я считаю, что нет. Подумайте о тех, кто будет поддерживать. Поставит кто-нибудь брейкпойнт в этом свойстве - и будет 30 раз тыкать, пока нужное пройдет. Сейчас я такими вот вещами занимаюсь. Наабстрагировали и науниверсилизировали настолько, что на перемещение иконки на 20 пикселей дают 4 дня. И почти хватает! Ну да, согласен - уже надо разбираться в чужом говнокоде. Но иногда лучше заставить одного бедолагу-новичка разбираться, чем всю команду - быдлокодить спагетти и ронять командный дух. Реально достаёт в каждом сеттере делать 1) проверку на null, 2) проверку на равество и 3) вызов оповещения изменения свойства. Это как минимум. buserДа-да... уличная магия... user7320Хотя в Постшарпе... Хм... уличная магия... user7320нашёл в Интернете... нет медленной рефлексии... Ну а вообще, в данном случае, домотканный код... лично мне симпатичнее непрозрачного посташрпа :) Хоть там оно и выглядит лучше :) В смысле "уличная магия"? Если что, я и не считаю, что написал что-то супер-пупер. Я вообще просто передрал. А что, в Постшарпе никто не знает, как оно всё работает? ))) ... |
|||
:
Нравится:
Не нравится:
|
|||
19.01.2014, 18:30 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320, ну постшарп инжектит свой код... если я не ошибаюсь... хотя... иногда это удобно... не засерается основная логика и т.п. ... ну и про ваш восторг по поводу неиспользования рефлексии в случае с универсальным сеттером использующим атрибуты [CallerMemberXXX] мне кажется необоснованным :) ... |
|||
:
Нравится:
Не нравится:
|
|||
19.01.2014, 18:49 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
buseruser7320, ну постшарп инжектит свой код... если я не ошибаюсь... хотя... иногда это удобно... не засерается основная логика и т.п. ... ну и про ваш восторг по поводу неиспользования рефлексии в случае с универсальным сеттером использующим атрибуты [CallerMemberXXX] мне кажется необоснованным :) Так это ж дотнетовский атрибут - может, там всякие липперты и Ко на ассемблере всё заоптимизировали? ))) ... |
|||
:
Нравится:
Не нравится:
|
|||
19.01.2014, 20:02 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320, реализация интерфейса INotifyPropertyChanged потребует ручного указания имени свойства которое было изменено и проверку перед присвоением. Данная реализация позволяет от этого избавиться. Следовательно есть смысл её применять. Возможный недостаток это наличие дополнительного вызова SetProperty в каждом свойстве. Можно добавить атрибут [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]. Еще вопрос насколько эффективно использование EqualityComparer. Если бы у нас были только ссылочные типы, то можно было бы использовать Object.Equals(obj1, obj2), но метод должен работать и с value типами. Как вариант можно написать общий метод для ссылочных типов и конкретные методы для value типов. Примерно так: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.
Будет ли от этого выигрыш - вопрос :) Решение с PostSharp безусловно самое красивое, но его есть смысл использовать только если в проекте уже используется PostSharp. Ставить его только ради NotifyPropertyChanged это как из пушки по воробьям. D129Подумайте о тех, кто будет поддерживать. Поставит кто-нибудь брейкпойнт в этом свойстве - и будет 30 раз тыкать, пока нужное пройдет. Не вижу проблемы в данном случае. Свойство продолжают оставиться независимыми так что ставь брейкпойнт ровно в том свйостве которое тебе нужно. Если ты говорил о методах SetProperty и OnPropertyChanged, то там помогут условные точки останова. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.01.2014, 20:52 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
bazileЕще вопрос насколько эффективно использование EqualityComparer. Если бы у нас были только ссылочные типы, то можно было бы использовать Object.Equals(obj1, obj2), но метод должен работать и с value типами. Как вариант можно написать общий метод для ссылочных типов и конкретные методы для value типов. Примерно так: ... Будет ли от этого выигрыш - вопрос :) Я думал над этим. Я, конечно, не спец в низкоуровневых штуках, но по-моему, проверка двух, например, числовых переменных на равенство и присвоение одной числовой переменно того же значения, что уже у неё есть - примерно одного порядка сложности операции. Может, даже присвоение быстрее. А вот для ссылочных типов проверка как раз нужна - они более громоздкие. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 05:37 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320Используй Code Snippets для написания свойств. Используй Expression для указания имени свойства в оповещении об изменении, если производительность позволяет. Всё остальное лишнее. Базовый класс. Парсер Expression . Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 05:59 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320нет медленной рефлексииРефлексию можно ускорить используя Emit или Expression. Вот пример "ускорителя" через Expression. Код: c# 1. 2. 3. 4.
... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 06:06 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
Я на данный момент использую свою модификацию вот этого решения . Рефлекшн применяется только при создании экземпляра модели, прочие вызовы используют expressions, и отсутствуют backing fields - в них просто нет надобности. Плюс декларативное описание зависимостей между свойствами и командами (я в своем варианте сделал разбор всего дерева зависимостей - т.е. если свойства B зависит от свойства А, а команда С зависит от свойства В, то при изменении свойства А команда С обязательно просмотрит изменения свойства В). ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 06:16 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
Алексей Кuser7320Используй Code Snippets для написания свойств. Используй Expression для указания имени свойства в оповещении об изменении, если производительность позволяет. Всё остальное лишнее. Базовый класс. Парсер Expression . Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
1. У вас в сеттере нет проверки на равенство. 2. Разборщик выражений разбирает только выражения доступа к полю или свойству - т. е. ваш код полезен только в выражениях, используемых для реализации INotifyPropertyCHanged и т. п., где не надо, например, получать имя вызывающего метода или события и т. п. Для более унифицированного использования таких вещей я делал портянку из кейсов Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24.
А выражения я и так использовал уже давно. Но решил уйти от них. Выражения нужны были из-за недостатка самого фреймворка - там всякие стэк трейсы, жёстко заданные строки и прочие костыли. Если теперь есть атрибут CallerMemberName - зачем выражения - все эти портянки костылей? Кроме того, CallerMemberName позволяет воспользоваться и старыми наработками из выражений - он же реализован в виде необязательного параметра, т. е. можно и свои значения имени передавать. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 06:22 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
Алексей К, а про сниппеты спасибо, что напомнили. Я про них всегда забываю. По идее, вы в чём-то правы - программные решения, не решающие конкретных задач (т. е. тех, над которыми вы работаете в данном проекте), а решающие задачи удобства написания кода, не должны смешиваться с логикой приложения, а должны выноситься в логику среды разработки. Потому что за удобство написания кода вашего приложения отвечает не ваше приложение, а среда разработки. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 06:31 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user73201. У вас в сеттере нет проверки на равенство.А так ли она нужна? Я обычно её делаю, только если она действительно нужна. А если делать универсальный механизм тут возникают вопросы какой компаратор использовать, например, в случае со строками. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 07:11 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user73202. Разборщик выражений разбирает только выражения доступа к полю или свойству - т. е. ваш код полезен только в выражениях, используемых для реализации INotifyPropertyCHanged и т. п., где не надо, например, получать имя вызывающего метода или события и т. п.Он ещё умеет формировать "путь к свойству", где-то это было надо, например: Код: c# 1.
Ну а так - да, он предназначен в основном для реализации INotifyPropertyChanged, на универсальность не претендует. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 09:20 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
bazile Если ты говорил о методах SetProperty и OnPropertyChanged, то там помогут условные точки останова. Очень помогут, если ты знаешь, что поставить как условие. А если как раз нет? А если уже знаешь, что ожидать в точке останова, то уже не надо и дебагировать.... Код надо писать, а не изголяться. Ну сколько у вас свойств - 50? 150? При любом изменении не-автор вашего решения - да еще в условиях прессинга (а так бывает) просто допишет свое, и не будет пользоваться вашей высокохудожественной поделкой. А вдруг - подумает каждый, кто не знаком лично с вами - этот код еще что-то вызывает, а мне это не нужно. :-/ :-) Не, это хорошо, что вы это знаете. Говорит об уровне. Но всегда должен стоять вопрос - чье время мы данным кодом экономим? Время процессора или время программиста, который придет на поддержку? ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 10:25 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
D129Но всегда должен стоять вопрос - чье время мы данным кодом экономим? Время процессора или время программиста, который придет на поддержку? Я хотел сэкономить в первую очередь своё время. А человек на поддержке должен хоть как-то хотя бы пытаться разобраться в коде, а не сходу писать своё. Там всего 3 строки - не лютый фреймворк. То ли дело у Алексея - мне даже сильно смотреть было лень по той ссылке, где он привёл кода на экран или больше. Я глянул мельком, что там чего-то много понаписано для какой-то простой вещи, и закрыл. ))) "В условиях прессинга" - это всё же не нормальный процесс разработки ПО. А то говнокод получается чаще в условиях именно прессинга, а потом уже когда "кто-то слишком много архитектурой балуется". А про дебаг не понял - ну я сам же и дебажил эту штуку, когда отлаживал - дебажиться без каких-либо извращений. Там всего-то три строчки. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 11:32 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320 Там всего-то три строчки. Я сейча работаю как раз с подобными (и даже еще большими) абстракциями. Знаете, сейчас мода - продавать проэкты, где якобы "весь" код не надо компилировать при изменениях - конфигурационные файлы. Призм, Меф, Кастл итп... Модные дизайнеры лишили в частности меня даже компилятора - если хочешь понять, кто вызывает конкретную функцию - то Студия показывает что никто. :-) Все поставляется через интерфейсы и конфигурационные связки. Меня уже трясет, когда я вижу очередной интерфейс с одним методом. При дебаггировании приходится ставить брейкпойнты наугад, иногда во всех методах класса, и если еще к этому добавить условный останов - когда вообще непонятно, что должно и куда прийти - аджайл же, нету никакой документации - то.... Говорю "большое спасибо" каждому ленивому умнику. :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 11:52 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
D129user7320 Там всего-то три строчки. Я сейча работаю как раз с подобными (и даже еще большими) абстракциями. Знаете, сейчас мода - продавать проэкты, где якобы "весь" код не надо компилировать при изменениях - конфигурационные файлы. Призм, Меф, Кастл итп... Модные дизайнеры лишили в частности меня даже компилятора - если хочешь понять, кто вызывает конкретную функцию - то Студия показывает что никто. :-) Все поставляется через интерфейсы и конфигурационные связки. Меня уже трясет, когда я вижу очередной интерфейс с одним методом. При дебаггировании приходится ставить брейкпойнты наугад, иногда во всех методах класса, и если еще к этому добавить условный останов - когда вообще непонятно, что должно и куда прийти - аджайл же, нету никакой документации - то.... Говорю "большое спасибо" каждому ленивому умнику. :-) Я могу вас понять. Могу посоветовать только переходить из тестеров в разработчики - будете сами всех так "удивлять". А вы это, свой продукт поддерживаете, или пытаетесь чужой код дебажить? Если чужой - то, может, от вас специально всё скрывают? С такими аджайлами и абстракциями и обфускации не нужны. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 11:58 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
D129, а зачем дебажить? Всё же на юнит-тестах делается. Тупо меняешь код, пока тесты не начнут проходить. Дебажить даже не надо. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 12:01 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320Я могу вас понять. Могу посоветовать только переходить из тестеров в разработчики - будете сами всех так "удивлять". А вы это, свой продукт поддерживаете, или пытаетесь чужой код дебажить? Если чужой - то, может, от вас специально всё скрывают? С такими аджайлами и абстракциями и обфускации не нужны. А я и есть разработчик. Но удивлять не могу. Слишком тупой для этого. Мой код прост и понятен - я два года писал модуль практически один, и когда уволился - мне от туда ни разу не позвонили. Значит разобрались без меня. Обфускации не нужны, потому, что клиент штучный. Правда, очень большой и богатый. Украсть программу для супермаркета можно только вместе с самим супермаркетом. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 12:12 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320D129, а зачем дебажить? Всё же на юнит-тестах делается. Тупо меняешь код, пока тесты не начнут проходить. Дебажить даже не надо. О, это то еще же горе..... Юнит тесты в бизнес-приложениях - это жупел. Проверка того, а работает ли поиск в классе List<> ? Ура! Работает! AssertTrue!!! бррр... ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 12:15 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320а зачем дебажить? Всё же на юнит-тестах делается. Тупо меняешь код, пока тесты не начнут проходить. Дебажить даже не надо. У тебя какое-то наивное представление о процессе разработки. Даже если код на 100% покрыт юнит-тестами, то все равно без отладки не получится обойтись. Не говорят уже о том что 100% покрытие встречается не так часто. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 12:35 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
D129О, это то еще же горе..... Юнит тесты в бизнес-приложениях - это жупел. Проверка того, а работает ли поиск в классе List<> ? Ура! Работает! AssertTrue!!! бррр... В самом деле "бррр.". Только это не вина юнит-тестов, а разработчика не понимающего что нужно тестировать, а что нет. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 12:36 |
|
|
start [/forum/topic.php?fid=20&fpage=131&tid=1403365]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
32ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
104ms |
get tp. blocked users: |
2ms |
others: | 11ms |
total: | 191ms |
0 / 0 |