0 / 0 / 0
Регистрация: 12.06.2015
Сообщений: 14
|
||||||
1 | ||||||
Преобразование типов, являющихся наследниками Attribute12.06.2015, 13:32. Показов 1106. Ответов 12
Метки нет (Все метки)
Здравствуйте. Столкнулся с такой проблемой. Читаю Шилдта и встретился мне такой пример:
0
|
12.06.2015, 13:32 | |
Ответы с готовыми решениями:
12
Преобразование типов в T Преобразование типов Преобразование типов Преобразование типов |
12.06.2015, 13:44 | 2 |
Вполне возможно. Это явное приведение типов.
Статический метод класса Attribute() GetCustomAttribute() имеет возвращаемый тип как Attribute() (то есть базовый тип для всех атрибутов). А вы просто явно приводите его к типу-наследнику (вашему атрибуту). Для исключения ошибки желательно бы еще проверить полученное значение на null.
0
|
0 / 0 / 0
Регистрация: 12.06.2015
Сообщений: 14
|
||||||
12.06.2015, 13:50 [ТС] | 3 | |||||
А почему тогда такое творение не работает? И в чем разница между этими ситуациями?
0
|
12.06.2015, 14:07 | 4 |
Сообщение было отмечено razamanaz как решение
Решение
Почему не работает? Если говорить точно, оно работает, только выбрасывает InvalidCastException (как и должно быть). Вы просто не совсем поняли.
В первом случае возвращаемое значение является, во первых типом Attribute() (поскольку это возвращаемый тип данного метода). И во вторых, поскольку вы извлекаете свой атрибут, оно же является и вашим собственным типом. Если оно им не является - так же получите InvalidCastException. Для того чтобы этого не было, можно использовать кс is или as.
1
|
0 / 0 / 0
Регистрация: 12.06.2015
Сообщений: 14
|
|
12.06.2015, 14:18 [ТС] | 5 |
Т.е. получается, что в возвращаемую переменную типа Attribute записывается адрес на переменную типа RemarkAttribute (что вполне допустимо),далее мы этот адрес передаем переменной re типа RemarkAttribute (все сходится). Я Вас правильно понимаю? Тогда возникает последний встречный вопрос: зачем выполнять явное приведение типов
RemarkAttribute re = (RemarkAttribute) Attribute.GetCustomAttribute(objForTypeMyClass, objForTypeOfAttribute);
0
|
12.06.2015, 14:23 | 6 |
Какие адреса? Еще раз: возвращаемый тип у этого метода - System.Attribute(). Но поскольку ваш класс является его наследником, и вы именно его извлекаете, то в вашем случае возвращаемый тип-тип вашего класса. Но поскольку переменная возврата типа System.Attribute() (то есть базового типа, в которой скрыт ваш собственный тип), то необходимо ее явно привести к вашему типу.
Добавлено через 1 минуту Вы можете и не приводить переменную, которую вам возвратил метод к вашему типу, но тогда она будет более "общего" типа System.Attribute().
0
|
Администратор
|
||||||
12.06.2015, 14:24 | 7 | |||||
razamanaz, ваш пример не соответствует ситуации по причине того, что Attribute.GetCustomAttribute() возвращает экземпляр класса RemarkAttribute, но приведённый к типу-родителю, т.е. Attribute
Вот такой код примерно повторяет код из первого сообщения
0
|
tezaurismosis
|
12.06.2015, 14:43
#9
|
Не по теме: insite2012, ваша правда :) Сообщение исправил.
0
|
12.06.2015, 14:49 | 10 |
razamanaz, просто поймите одну вещь. Когда разработчики писали FCL (и конкретно этот метод), они, естественно, не могли предугадать, какого типа будет возвращенная переменная. Именно потому они и сделали возвращаемый тип как System.Attribute(), как общий для всех атрибутов (как встроенных в FCL, так и пользовательских). А какой точно тип-известно тому, кто применяет этот метод.
И да, второй момент. Сам объект не меняется (применительно к вашему коду). Он остается тем же самым, но поскольку ссылка на него (именно ссылка, а не сам объект) имеет тип базового класса, то все, что определено в самом объекте и не относится к базовому типу, компилятор скрывает. Вам доступно только то, что есть в базовом классе. Все что есть в наследнике не пропадает, оно просто (до явного приведения типов) не видно. В конце концов, язык же со строгой типизацией, и компилятор за этим следит.
1
|
0 / 0 / 0
Регистрация: 12.06.2015
Сообщений: 14
|
|
12.06.2015, 14:56 [ТС] | 11 |
По поводу приведения типов понял. Но непонятно, в чем ошибки моих процитированных размышлений?
0
|
12.06.2015, 14:59 | 12 |
Во первых, зачем вы пытаетесь манипулировать понятие "адрес" В C# оно просто не нужно. Есть переменная, есть объект, и так далее. А какие у них адреса, и так далее-это уже не нужно.
Ну а суть я вам рассказал. Разницу между типом ссылки (указателя на объект) и типом самого объекта.
1
|
0 / 0 / 0
Регистрация: 12.06.2015
Сообщений: 14
|
|
12.06.2015, 15:02 [ТС] | 13 |
Спасибо всем! Вообщем, думаю, что разобрался!
0
|
12.06.2015, 15:02 | |
12.06.2015, 15:02 | |
Помогаю со студенческими работами здесь
13
Преобразование типов Преобразование типов Преобразование типов Преобразование типов Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |