|
Вызов GetType()
|
|||
---|---|---|---|
#18+
Читал тут одну книжку и в ней наткнулся на такой код Код: 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. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48.
Хотел узнать, а зачем вызов GetUnproxiedType() в Equals? Почему нельзя было просто вызвать other.GetType() и this.GetType()? ... |
|||
:
Нравится:
Не нравится:
|
|||
13.11.2012, 20:33 |
|
Вызов GetType()
|
|||
---|---|---|---|
#18+
Книжку писал пьяный песатель, видимо. Что за чтиво-то? ... |
|||
:
Нравится:
Не нравится:
|
|||
13.11.2012, 23:20 |
|
Вызов GetType()
|
|||
---|---|---|---|
#18+
МСУКнижку писал пьяный песатель, видимо. Что за чтиво-то? Сам ты пьяный писатель, но в книжке тоже есть ошибка. Книжка NHibernate CookBook . Lamo2012Хотел узнать, а зачем вызов GetUnproxiedType() в Equals? Почему нельзя было просто вызвать other.GetType() и this.GetType()? Дело в том, что NHibernate делает динамические прокси классы, которые наследуют от классов доменной модели. Если вызвать на таком класси GetType(), то это будет не ваш класс, а класс с названием ProxyМногобукв. При этом внутри этого прокси-класса есть ссылка на настоящий класс. Чтобы сравнить реальные типы и нужен GetUnproxiedType, только он должен быть с модификатором Protected или public. Волшество в том, что при таком раскладе проки-тип перенапривит вызов реальному типу, и вернёт его тип. Но для private методов такое волшебство не работает, т.к. они не переопределятеся прокси-типом. Поэтому private GetUnproxiedType() вернёт ProxyМногобукв, а public или protected GetUnproxiedType() вернёт тип доменной модели. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.11.2012, 23:35 |
|
Вызов GetType()
|
|||
---|---|---|---|
#18+
SolYUtor, только пьяный архитектор может шунтировать классы подобными костылями. ((INHibernateProxy)proxy).HibernateLazyInitializer.PersistentClass тебе в помощь. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.11.2012, 23:49 |
|
Вызов GetType()
|
|||
---|---|---|---|
#18+
МСУ, отличии от твоего это 100% рабочий способ, не говоря уже о простоте. Ибо ((INHibernateProxy)proxy).HibernateLazyInitializer.PersistentClass будеть падать с InvalidCastException на свежесозданных Transient сущностях. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.11.2012, 00:01 |
|
Вызов GetType()
|
|||
---|---|---|---|
#18+
SolYUtor, то, что этот гавнокод работает еще не означает, что подобный подход правильный. Недокументированные приемы - зло. Кстати, туда же: HibernateLazyInitializer.GetImplementation() ... |
|||
:
Нравится:
Не нравится:
|
|||
14.11.2012, 00:21 |
|
Вызов GetType()
|
|||
---|---|---|---|
#18+
SolYUtor, Немного офтопа, а как Ваше мнение, на сегодняшний момент, можно бы было уйти от прокси, а маркировать реальные объекты, для кеширования, обновления из кеша и тд,?, поднялось бы быстродействие, была бы более изящное решение? ... |
|||
:
Нравится:
Не нравится:
|
|||
14.11.2012, 00:23 |
|
Вызов GetType()
|
|||
---|---|---|---|
#18+
SolYUtorДело в том, что NHibernate делает динамические прокси классы, которые наследуют от классов доменной модели. Если вызвать на таком класси GetType(), то это будет не ваш класс, а класс с названием ProxyМногобукв. Ну собственно это в книжке и написано. SolYUtorПри этом внутри этого прокси-класса есть ссылка на настоящий класс. Возможно. Но откуда методу GetUnproxiedType() об этом знать и как он вызовет GetType() у этого настоящего класса, если его реализация, описанная в книжке есть this.GetType()? SolYUtorЧтобы сравнить реальные типы и нужен GetUnproxiedType, только он должен быть с модификатором Protected или public. Волшество в том, что при таком раскладе проки-тип перенапривит вызов реальному типу, и вернёт его тип. Но для private методов такое волшебство не работает, т.к. они не переопределятеся прокси-типом. Поэтому private GetUnproxiedType() вернёт ProxyМногобукв, а public или protected GetUnproxiedType() вернёт тип доменной модели. Вот тут у меня почему-то стойкое убеждение что реализация Object.GetType() вернет именно "Точный тип текущего экземпляра в среде выполнения", а не что-то иное, т.е. в каком бы из родительских для прокси-класса метод описан не был, все равно будет возвращен именно тот тип, который создавался средой выполнения, а именно ПроксиЧегоТо. Правильно ли я думаю? ... |
|||
:
Нравится:
Не нравится:
|
|||
14.11.2012, 09:14 |
|
Вызов GetType()
|
|||
---|---|---|---|
#18+
МСУSolYUtor, только пьяный архитектор может шунтировать классы подобными костылями. ((INHibernateProxy)proxy).HibernateLazyInitializer.PersistentClass тебе в помощь.Ужас какой. :-) Для сравнения, в EF это решается, на мой взгляд, более элегантно: Код: c# 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
14.11.2012, 09:30 |
|
Вызов GetType()
|
|||
---|---|---|---|
#18+
SolYUtor, Сейчас для меня иерархия классов, строящаяся на основе описанного в книжке базового типа при работе NH представляется вот так: Код: 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. 36. 37. 38. 39.
И я не понимаю, почему private Type GetUnproxiedType() { return GetType(); } должен возвращать тип, в котором он описан, и уж тем более именно тип предка прокси, а не сам тип прокси? ... |
|||
:
Нравится:
Не нравится:
|
|||
14.11.2012, 10:38 |
|
Вызов GetType()
|
|||
---|---|---|---|
#18+
Lamo2012И я не понимаю, почему private Type GetUnproxiedType() { return GetType(); } должен возвращать тип, в котором он описан, и уж тем более именно тип предка прокси, а не сам тип прокси? Вы невнимательно читали. Есть класса А, и хибер вернул вам ПроксиА. ПроксиА содержит ссылку на А, и GetUproxiedType вызовет GetUnproxiedType на экземпляре А, но не ПроксиА, при условии, что GetUnproxiedType public | protected virtual. Просто GetType вызовется на экземпляре ПроксиА, и вернёт тип прокси. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.11.2012, 11:06 |
|
Вызов GetType()
|
|||
---|---|---|---|
#18+
Lamo2012, аналогия грубая, но принцип такой. Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
... |
|||
:
Нравится:
Не нравится:
|
|||
14.11.2012, 11:10 |
|
Вызов GetType()
|
|||
---|---|---|---|
#18+
Забыл наследования добавить. Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
... |
|||
:
Нравится:
Не нравится:
|
|||
14.11.2012, 11:12 |
|
Вызов GetType()
|
|||
---|---|---|---|
#18+
SolYUtor, Спасибо! Ваши ответы как всегда на высоте! Я тут тоже нашел аналогичный ответ на этот вопрос. Суть вот в чем "I actually went ahead and wrote to the author of the book about this code. It turns out this is due to how the proxy wrapping works. Here is his response: "If you don't understand how the proxy frameworks work, the idea can seem magical. When NHibernate returns a proxy for the purposes of lazy loading, it returns a proxy instance inherited from the actual type. There are a few members we can access without forcing a load from the database. Among these are proxy's Id property or field, GetType(), and in some circumstances Equals() and GetHashCode(). Accessing any other member will force a load from the database. When that happens, the proxy creates an internal instance. So, for example, a lazy loaded instance of Customer (CustomerProxy102987098721340978), when loaded, will internally create a new Customer instance with all of the data from the database. The proxy then does something like this: Код: c# 1. 2. 3. 4. 5. 6. 7.
Incidentally, it's this overriding that requires everything to be virtual on entities that allow lazy loaded. So, all calls to the Name property on the proxy are relayed to the internal Customer instance that has the actual data. GetUnproxiedType() takes advantage of this. A simple call to GetType() on the proxy will return typeof(CustomerProxy02139487509812340); A call to GetUnproxiedType() will be relayed to the internal customer instance, and the internal customer instance will return typeof(Customer)."" Спасибо всем, кто откликнулся. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.11.2012, 11:21 |
|
|
start [/forum/topic.php?fid=20&tid=1405655]: |
0ms |
get settings: |
10ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
64ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
48ms |
get tp. blocked users: |
1ms |
others: | 330ms |
total: | 484ms |
0 / 0 |