|
Универсальные getter и setter
|
|||
---|---|---|---|
#18+
Надоело писать подобное для каждого свойства Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
Надоело копипастить. Решил придумать, как бы покороче. Самое простое, что пришло в голову: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.
Ну и строковые параметры имён свойств приходят через выражения (Expression), так что хардкодинга, вроде, нет, и рефакторинг спасён. Проблема в том, что хотелось бы избежать возвращаемых и принимаемых типов object, чтобы не приходилось заниматься приведением типов. Вроде, как-то это можно через шаблоны (generics) сделать. Как? Подскажите, пожалуйста. И ещё такой вопрос, в чём минусы такой реализации универсальных свойств? Вы как делаете - копипастите везде одинаковый по сути код для шаблонных свойств (т. е. это для вас не проблема), или что-то подобное, как у меня используете? Я пока минус вижу только в том, что в таком виде нельзя реализовать специальную логику для каждого свойства. Может, потом как-нибудь придумаю, как логику передавать в эти универсальные свойства - может, через делегаты или выражения. Вобщем, хотелось бы мнения послушать. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2013, 09:36 |
|
Универсальные getter и setter
|
|||
---|---|---|---|
#18+
user7320, использую code snippets. То есть набираешь всего одно слово и подставляется кусок кода. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2013, 09:46 |
|
Универсальные getter и setter
|
|||
---|---|---|---|
#18+
user7320 Код: sql 1. 2. 3. 4. 5.
Это подходит только для простых autoimplemented propertieis. Со свойствами c backing field - уже работать не будет, хотя это самый простой случай. А свойства еще могут принимать/возвращать значения свойств агрегируемого объекта. Да и просто включать в себя некую нелинейную логику. Вы как делаете - копипастите везде одинаковый по сути код для шаблонных свойств (т. е. это для вас не проблема), или что-то подобное, как у меня используете? Просто вызываю PropertyChanged, передавая имя свойства через Expression<Func<T, TProperty>> - это избавляет от хардкодинга имен свойств. Для всего остального средства на все случаи жизни не придумаешь. SolYUtor Решение уже готово. А как у этой штуки обстоят дела со сложно устроенными свойствами? И логика вызова OnPropertyChanged тоже может быть далеко не линейной. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2013, 10:02 |
|
Универсальные getter и setter
|
|||
---|---|---|---|
#18+
Сон Веры Павловны, если у вас сложная логика вызова свойств, вы можете попросить Fody.PropertyChanged не переписывать свойтсво, и сделать вызов руками. Для остальных 99% случае можно использовать безбоязненно, экономит массу времени, сильно упрощает код. Распознаёт зависимости между свойствами, и делает вызовы соотвественно. Если интересно, как оно делает - возмите dotpeek, да посмотрите результат. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2013, 10:06 |
|
Универсальные getter и setter
|
|||
---|---|---|---|
#18+
petalvikuser7320, использую code snippets. То есть набираешь всего одно слово и подставляется кусок кода.+1 ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2013, 10:18 |
|
Универсальные getter и setter
|
|||
---|---|---|---|
#18+
Алексей К, IL-Weaving не используете принципиально? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2013, 10:39 |
|
Универсальные getter и setter
|
|||
---|---|---|---|
#18+
SolYUtorАлексей К, IL-Weaving не используете принципиально?У меня основная масса сущностей генерируется через T4 по БД или WSDL. А для небольшого числа остальных случаев возможностей снипетов хватает. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2013, 10:46 |
|
Универсальные getter и setter
|
|||
---|---|---|---|
#18+
user7320, Может тебе стоит в таких случаях ОБОБЩЕННЫЕ МЕТОДЫ ИСПОЛЬЗОВАТЬ один раз обьявил а дальше подставляешь любой тип в конструктор ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2013, 11:57 |
|
Универсальные getter и setter
|
|||
---|---|---|---|
#18+
VIT2708user7320, Может тебе стоит в таких случаях ОБОБЩЕННЫЕ МЕТОДЫ ИСПОЛЬЗОВАТЬ один раз обьявил а дальше подставляешь любой тип в конструктор Да, я как раз и спрашивал, как это сделать. Я обозвал это шаблонами. Я уже сделал: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
Вобщем, как я понял... Поскольку этот код решает только задачу копипаста, то лучше эту задачу переложить на коллекцию сниппетов, чем засорять код. Тем более, что рефлексия накладывает свои дополнительные расходы. Все подобные "универсальные методы" на самом деле не универсальны в той или иной степени, и только добавляют сложности тем, кто с ними не знаком - видеть какие-то незнакомые атрибуты или какую-то рефлексию на простых участках, вместо обычного и простого кода... Я правильно понимаю? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2013, 14:13 |
|
Универсальные getter и setter
|
|||
---|---|---|---|
#18+
У меня чисто такой вопрос, не по теме. У вас Cancel в диалоге редактирования EMail есть? И если да, то как реализовано возвращение предыдущих значений? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2013, 14:44 |
|
Универсальные getter и setter
|
|||
---|---|---|---|
#18+
АбсолютУ меня чисто такой вопрос, не по теме. У вас Cancel в диалоге редактирования EMail есть? И если да, то как реализовано возвращение предыдущих значений? Если я вас правильно понимаю, то вы говорите о том случае, когда модель представления (МП) содержит в себе объект модели (М) в качестве поля, и когда значения полей этой М изменяются при редактировании контролов представления (П), представляющих собой поля М (через привязанные свойства МП). Т. е. получается, что когда, например, контрол адреса е-мейла теряет фокус, то поле е-мейла М автоматически получает новое значение. При этом старое значение теряется и его уже не вернуть. Ну, для этого, как я думаю (сам я такого не делал) либо организуете буферный объект, который будет хранить в себе текущую копию модели с изменениями, и по Submit копировать заменять текущий объект М буферным, либо по Cancel удалять буферный и оставлять текущую М без изменений. Либо ещё вариант, когда у вас есть репозиторий, то буфером в этом случае является сама М. После Submit вы вызываете из репозитория Update и обновляете значение в репозитории текущей М. По Cancel - просто ничего не делаете с репозиторием, в результате у вас сохранились старые значения. Самое же простое, изменять поля М не после потери фокуса каждым контролом, а после нажатия Submit изменять уже всю М целиком по МП с уже сделанными изменениями. Как-то так. Вроде, элементарно? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2013, 16:35 |
|
Универсальные getter и setter
|
|||
---|---|---|---|
#18+
user7320Самое же простое, изменять поля М не после потери фокуса каждым контролом, а после нажатия Submit изменять уже всю М целиком по МП с уже сделанными изменениями. Только с мгновенной валидацией придётся распрощаться - только общая сводка после Submit. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2013, 16:40 |
|
Универсальные getter и setter
|
|||
---|---|---|---|
#18+
user7320, что-то как-то перебор (имо). Я от программирования слегка отошел уже, но все же помню некоторые вещи. И я все же смотрю сквозь WPF, если что. Вот, что меня слегка смутило: user7320get { return _customer.Email; } set { if (value == _customer.Email) return; _customer.Email = value; OnPropertyChanged("Email"); } Т.е. такой подход уже подразумевает некий темп объект, который при Cancel восстановит исходное значение Email'а. Как хороший пример - реализация IEditableObject Но почему бы сразу не сделать темповые проперти, к примеру, такие: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
И при субмите уже сетить, в противном случае просто закрывать. Вроде я так делал в своё время. И что бы не писать по 100 раз OnPropertyChanged у меня была реализация SetPropertyAndNotifity(Expression, ref, value) ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2013, 16:59 |
|
Универсальные getter и setter
|
|||
---|---|---|---|
#18+
user7320Только с мгновенной валидацией придётся распрощаться - только общая сводка после Submit. Это не приемлемо вообще никак и никогда :) ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2013, 17:07 |
|
Универсальные getter и setter
|
|||
---|---|---|---|
#18+
авторВот, что меня слегка смутило: Это из джошесмитовского примера скопировано: У МП есть объект М в качестве поля _customer. Свойства МП привязаны к контролам П и изменяются по потере соответствующими контролами фокуса, либо по изменению свойства. В логике МП изменение свойства МП сразу (ну, после некоторой валидации) меняет свойства лежащей в основе М. Как писал Джош Смит, МП вовсе не содержит в себе копию М, а "пробрасывает", предоставляет для МП значения свойств М. Так что если где и содержится "нетронутая" копию предыдущих данных, так это в репозитории и в лежащим под ним конкретном хранилище данных. Нажав Cancel, мы (по сценарию примера Джоша) закрываем П сущности, одновременно уничтожается её МП и М, лежащая в основе. Точнее, не уничтожается, а становится "ненужной" (сборщик мусора и всё такое). Тогда да, данные остаются нетронутыми в репозитории. Вообще, я сначала вас не понял, и подумал, что вы хотите реализовать сценарий, когда каждое свойство сущности редактируется по шагам - одна страница - е-мейл, вторая - имя и т. д. И вам надо, чтобы можно было нажать на Cancel и вернуться на предыдущую страницу, где должны сохраниться ранее введённые значения... Что-то типа такого. Вобщем, я перепутал. Даже в этом сценарии, пожалуй, дополнительный буферный объект не нужен. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2013, 19:50 |
|
Универсальные getter и setter
|
|||
---|---|---|---|
#18+
user7320джошесмитовского Да ну его. Только кровь всем портит. user7320Вообще, я сначала вас не понял, и подумал, что вы хотите реализовать сценарий, когда каждое свойство сущности редактируется по шагам - одна страница - е-мейл, вторая - имя и т. д. Нет, я не про визарды и не про шаговую. Суть моего диалога тут - просто размышление. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2013, 19:57 |
|
|
start [/forum/topic.php?fid=20&fpage=156&tid=1404401]: |
0ms |
get settings: |
10ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
43ms |
get topic data: |
12ms |
get forum data: |
2ms |
get page messages: |
55ms |
get tp. blocked users: |
2ms |
others: | 14ms |
total: | 159ms |
0 / 0 |