|
Универсальный 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 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
Алексей К, ну в данном случае expression вряд ли будет быстрее рефлекшена. Если собрать через него выражение аналогичное рефлекшену и закешировать тогда да. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 12:56 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
bazileuser7320а зачем дебажить? Всё же на юнит-тестах делается. Тупо меняешь код, пока тесты не начнут проходить. Дебажить даже не надо. У тебя какое-то наивное представление о процессе разработки. Даже если код на 100% покрыт юнит-тестами, то все равно без отладки не получится обойтись. Не говорят уже о том что 100% покрытие встречается не так часто. А сами тесты надо дебажить? ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 12:57 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
Алексей К, а переписать свою библиотеку через CallerMemberName пробовали? Может, там всё ужмётся в разы. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 12:58 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
netivanАлексей К, ну в данном случае expression вряд ли будет быстрее рефлекшена. Если собрать через него выражение аналогичное рефлекшену и закешировать тогда да.Ну я и предложил с оговоркой, что если производительность позволяет. А она скорее всего позволяет, это же отображение данных, их при отображении обычно много не бывает. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 12:59 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320Алексей К, а переписать свою библиотеку через CallerMemberName пробовали? Может, там всё ужмётся в разы.Если честно, первый раз его вижу. Тут надо подумать. :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 13:01 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320Алексей К, а переписать свою библиотеку через CallerMemberName пробовали? Может, там всё ужмётся в разы.Оно под 4.5, а мне под 4.0 надо. :-( ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 13:03 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
Алексей КnetivanАлексей К, ну в данном случае expression вряд ли будет быстрее рефлекшена. Если собрать через него выражение аналогичное рефлекшену и закешировать тогда да.Ну я и предложил с оговоркой, что если производительность позволяет. А она скорее всего позволяет, это же отображение данных, их при отображении обычно много не бывает. ну понятно, хотя вдруг обновление грида 1 млн в секунду, вот там будет заметно. Да и вообще можно и string передавать, ничего криминального не вижу тут.Раздули из такой фигни целую тему) ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 13:05 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
netivanну понятно, хотя вдруг обновление грида 1 млн в секунду, вот там будет заметно.Уверен, там тонкое место будет в другом месте. :-) netivanДа и вообще можно и string передавать, ничего криминального не вижу тут.Если будет ошибка в имени свойства - её будет непросто отловить. С Expression как-то спокойнее. :-) netivanРаздули из такой фигни целую тему)Я узнал про CallerMemberName, значит не зря. :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 13:14 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320Алексей К, а переписать свою библиотеку через CallerMemberName пробовали? Может, там всё ужмётся в разы. Вряд ли в разы - это решение решает только проблему вызова PropertyChanged, backing fields и логика оповещения зависимостей будет всё так же присутствовать. Решение по ссылке, которую я постил на предыдущей странице, действительно ощутимо сжимает код (базовый класс модели получился достаточно объемным). Единственное "но" этого решения - строчные именования свойств в атрибуте описания зависимости, но это решается рантаймовой проверко в конструкторе. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 15:13 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
bazileчто нужно тестировать, а что нет. Ну это вообще я поприкалывался раз - на заседации. Купили "Ковертюру" - это для джавы такая утилита, которая как раз замеряет покрытие юнит-тестами. (этож еще деньги на этом зарабатывают!!! ) И она дает 25%. Полно кода, где юнит тестить просто нечего. То есть, абсолютно. А обсуждался вопрос, как пометить едиообразно те методы, которая Кю вертюра брать в рассчет не должна. А я им рассказал случай, из геологической практики моих родителей - Когда некий руководитель получил от буровиков соц. обязательства - обеспечить выход керна 78%. Начал возмущаться - как это 78%!!! Вся страна берет повышенные обязательства - 106% , даже 110%!!! А вы только 78!!!! Не менее 103 должно быть! Я им и сказал - что не надо насиловать инструмент, то, что данный тип аппликации покрыт на 25% - это научный факт. Норма. Изменится тип проэкта - изменится и цифра. Незачем вносить в код то, что не код. :-))) ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 16:44 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
D129bazileчто нужно тестировать, а что нет. Ну это вообще я поприкалывался раз - на заседации. Купили "Ковертюру" - это для джавы такая утилита, которая как раз замеряет покрытие юнит-тестами. (этож еще деньги на этом зарабатывают!!! ) И она дает 25%. Полно кода, где юнит тестить просто нечего. То есть, абсолютно. А обсуждался вопрос, как пометить едиообразно те методы, которая Кю вертюра брать в рассчет не должна. А я им рассказал случай, из геологической практики моих родителей - Когда некий руководитель получил от буровиков соц. обязательства - обеспечить выход керна 78%. Начал возмущаться - как это 78%!!! Вся страна берет повышенные обязательства - 106% , даже 110%!!! А вы только 78!!!! Не менее 103 должно быть! Я им и сказал - что не надо насиловать инструмент, то, что данный тип аппликации покрыт на 25% - это научный факт. Норма. Изменится тип проэкта - изменится и цифра. Незачем вносить в код то, что не код. :-))) Ваши проблемы от того, что у ваших заказчиков до... денег. Вот и беситесь с жиру, выкидываете бабки на всякие утилиты, и без которых ясно, что к чему... С другой стороны, всяким кувертюрам тоже жить надо - у них свои семьи, дети. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 16:53 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320всяким кувертюрам тоже жить надо - у них свои семьи, дети. Вопрос только в том, когда падет Рим. :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
20.01.2014, 17:04 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320Дело опять касается 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.
Ну вот и первый камушек... Значит, в MVVM, если мы используем модель как поле, хранящее значение свойств модели представления (т. е. в самой модели представления отдельных полей для хранения значений свойств нет), то так, как я выше написал в сеттере, сделать нельзя. Т. е. если имеем Код: c# 1. 2. 3. 4.
То вот так сделать нельзя Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Т. к. получим исключение "A property, indexer or dynamic member access may not be passed as an out or ref parameter". А получится сделать вот так Код: c# 1. 2. 3. 4. 5. 6.
Кто-нибудь может подсказать, как обойти это? Или как реализацию SetProperty поменять, чтобы и для таких случаев срабатывало? ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2014, 14:20 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
Код: c# 1. 2. 3. 4.
... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2014, 14:40 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320 Кто-нибудь может подсказать, как обойти это? Или как реализацию SetProperty поменять, чтобы и для таких случаев срабатывало? Код: c# 1. 2. 3. 4. 5. 6. 7.
:-)))))))))))) ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2014, 14:43 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
D129user7320Кто-нибудь может подсказать, как обойти это? Или как реализацию SetProperty поменять, чтобы и для таких случаев срабатывало? Код: c# 1. 2. 3. 4. 5. 6. 7.
:-))))))))))))Нет! В этом случае с программой разберётся любой посторонний. Нам это не надо! :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2014, 14:46 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
D129user7320Кто-нибудь может подсказать, как обойти это? Или как реализацию SetProperty поменять, чтобы и для таких случаев срабатывало? Код: c# 1. 2. 3. 4. 5. 6. 7.
:-)))))))))))) А где тут присвоение значения? Алексей К Код: c# 1. 2. 3. 4.
А выполнение? Что-то типа такого? Код: c# 1. 2. 3. 4. 5.
А как такую проверку сделать? Код: c# 1. 2. 3. 4.
Не пойму, как вытащить field из тела выражения. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2014, 16:51 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
Т.е., там можно даже без выражения - сразу делегат. Но всё равно не понятно, как сделать проверку старого и нового значения поля. Разве что ещё один параметр ввести - старое значение поля - и делать сравнение в SetProperty - если не равны, то выполнять делегат, а если равны, то не выполнять? ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2014, 16:54 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320У тебя от экспешенов уже крыша поехала. :-) Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2014, 17:00 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320и делать сравнение в SetProperty - если не равны, то выполнять делегат, а если равны, то не выполнять? Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
И вот реализация (!!!) NotifyPropertyChanged: Код: c# 1. 2. 3. 4. 5. 6. 7.
Транспортное средство двухколесное изобретать будем? :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2014, 17:01 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320Напиши уже T4 Template какой-нибудь или кодогенератор для XML. Там работы на 20 минут. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2014, 17:08 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
Или вообще вот так: Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
Тут пример реализации. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2014, 17:17 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
Если надо работать с инкапсулированной моделью оно будет выглядеть так: Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2014, 17:20 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
D129user7320и делать сравнение в SetProperty - если не равны, то выполнять делегат, а если равны, то не выполнять? Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
И вот реализация (!!!) NotifyPropertyChanged: Код: c# 1. 2. 3. 4. 5. 6. 7.
Транспортное средство двухколесное изобретать будем? :-) У вас всё стандартно. А у меня - инкапсулировано в базовом классе. Мне надо только унаследоваться от этого базового класса и в нужном виде (см. мой ответ Алексею ниже) писать сеттер. Кстати, NotifyPropertyChanged - лучше через временную переменную : Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
Алексей Кuser7320У тебя от экспешенов уже крыша поехала. :-) Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Спасибо. Сеттер, конечно, чего-то разросся: Код: c# 1.
Надеюсь, больше косяков не всплывёт, а то, если ещё придётся сеттер усложнять, то придётся, наверное, бросить эту затею с универсальным сеттером. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2014, 17:25 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
Алексей КИли вообще вот так: Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
Тут пример реализации. Пока что моё своёство с двумя лямбдами выглядит приятнее. )) ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2014, 17:28 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320А зачем тебе проверка на равенство старого и нового значения? Если для красоты, то оно того не стоит. :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2014, 17:41 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
Алексей Кuser7320А зачем тебе проверка на равенство старого и нового значения? Если для красоты, то оно того не стоит. :-) Стоит. 1. При равенстве я не вызываю PropertyChanged. 2. Соответственно 1, не срабатывают байндинги. 3. Не вызывается цепочка сеттеров в случае, что я описал выше - т. е. когда модель представления не хранит свои копии значений свойств модели, а "пробрасывает" их в модель. И это в простом случае, когда у меня только VM и M, а если таких пробрасывателей больше? Ну и апелляция к авторитетам . ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2014, 19:32 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
D129user7320Ну и апелляция к авторитетам . Наконец то! :-))))) А вы, я так понимаю, против всяких универсальных сеттеров и максимум за что за - чтобы то стандратное, что вы выше приводили, генерилось сниппетами или шаблонами? Ну и потом в region'ы всё это непотребство спрятать, чтобы глаза не мозолило? ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2014, 19:49 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
Еще можно Castle.DynamicProxy использовать. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2014, 01:31 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320Стоит.Нет. Это "экономия на спичках" за редкими исключениями. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2014, 06:12 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
Алексей Кuser7320Стоит.Нет. Это "экономия на спичках" за редкими исключениями. Цепочки сеттеров, байндинги и лишние события - причём почти всегда это всё одновременно - "экономия на спичках"? При том, что нам сделать такую проверку ничего не стоит - вынес в базовый класс и написал один раз две строчки кода. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2014, 09:57 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
Алексей Кuser7320Стоит.Нет. Это "экономия на спичках" за редкими исключениями. Приведите пример исключения, пожалуйста. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2014, 09:57 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320При том, что нам сделать такую проверку ничего не стоит - вынес в базовый класс и написал один раз две строчки кода.Ну тебе виднее. :-) user7320Алексей КНет. Это "экономия на спичках" за редкими исключениями. Приведите пример исключения, пожалуйста.Ну может, как ты и говорил, производительность. Хотя, в сеттерах медленного кода по идее быть не должно. Пока всё. Если ещё что придумаю - отпишу. :-) зы: Не стоит забывать, что в DependencyProperty, к которому выполняется привязка, есть встроенная проверка на равенство старого и нового значения. Делай выводы. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2014, 10:05 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
Алексей Кuser7320При том, что нам сделать такую проверку ничего не стоит - вынес в базовый класс и написал один раз две строчки кода.Ну тебе виднее. :-) user7320пропущено... Приведите пример исключения, пожалуйста.Ну может, как ты и говорил, производительность. Хотя, в сеттерах медленного кода по идее быть не должно. Пока всё. Если ещё что придумаю - отпишу. :-) зы: Не стоит забывать, что в DependencyProperty, к которому выполняется привязка, есть встроенная проверка на равенство старого и нового значения. Делай выводы. Ну так мы делаем проверку раньше, чем это делает DependencyProperty, и, поскольку при равенстве мы значение не изменяем и событие изменения не вызываем, то и DependencyProperty никаких проверок не делает, т. к. байндинг не срабатывает. Но DependencyProperty это частный пример. Подстраивать каждый раз модель под то, будет она работать с DependencyProperty или с чем-то другим - муторно. Ну а так я согласен - где-то выиграешь, где-то проиграешь. Для меня, по крайней мере, плюс в том, что проверку я сам делаю осознанно, а про проверку в DependencyProperty могу и забыть. Ну а если по коллекции проходишься и делаешь изменения - тогда уже не "экономия на спичках"? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2014, 10:14 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320Ну а если по коллекции проходишься и делаешь изменения - тогда уже не "экономия на спичках"?Ну сколько там записей? Тысяча, не больше поди... ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2014, 12:07 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
И вообще, это попахивает преждевременной оптимизацией. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2014, 12:09 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
Алексей КИ вообще, это попахивает преждевременной оптимизацией. А без проверок - недостаточная длина кода. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2014, 12:21 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320Алексей КИ вообще, это попахивает преждевременной оптимизацией. А без проверок - недостаточная длина кода.Это да. :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2014, 12:29 |
|
Универсальный setter
|
|||
---|---|---|---|
#18+
user7320D129пропущено... Наконец то! :-))))) А вы, я так понимаю, против всяких универсальных сеттеров и максимум за что за - чтобы то стандратное, что вы выше приводили, генерилось сниппетами или шаблонами? Ну и потом в region'ы всё это непотребство спрятать, чтобы глаза не мозолило? Я не поленюсь и написать, печатаю я быстро, да и не особо нужно сейчас печатать - с автоподсказками-то... Регионы - зло. Все в коде, что не код - должно быть стерто. Мне приходилось работать с файлами кода по 12 тысяч строк. Каждый раз, когда я в том файле встречал регион - я стирал его со словами - ты, гад, еще и скрыть от меня что-то хочешь? :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
26.01.2014, 13:20 |
|
|
start [/forum/topic.php?all=1&fid=20&tid=1403365]: |
0ms |
get settings: |
7ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
86ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
80ms |
get tp. blocked users: |
1ms |
others: | 10ms |
total: | 217ms |
0 / 0 |