Здравствуйте, Воронков Василий, Вы писали:
ВВ>Не верю.
Зря. Вот тебе пример.
var asm = AppDomain.CurrentDomain.DefineDynamicAssembly(
new AssemblyName("asm"), AssemblyBuilderAccess.Run);
var mdl = asm.DefineDynamicModule("main");
var type = mdl.DefineType("MyType");
var getter =
type.DefineMethod(
"gEt-PrOp",
MethodAttributes.Public | MethodAttributes.SpecialName,
typeof (int),
new Type[0]);
var gen = getter.GetILGenerator();
gen.Emit(OpCodes.Ldc_I4_3);
gen.Emit(OpCodes.Ret);
var prop =
type.DefineProperty(
"Prop",
PropertyAttributes.None,
typeof (string),
new Type[0]);
prop.SetGetMethod(getter);
var createdType = type.CreateType();
var propInfo = createdType.GetProperty("Prop");
Console.WriteLine(propInfo.GetValue(Activator.CreateInstance(createdType), null));
Console.WriteLine(createdType.GetMethod("get_Prop") != null);
ВВ> Т.к. если выйдет такое "обновление", то весь существующий код на фиг отвалится. ВВ>obj.Property = "value"; ВВ>транслирует в ВВ>call instance set_Property
Компилятор шарпа и компилятор МС++ читают метаданные и используют токены реальных методов, а не тупо формируют строчку конкатенацией, так что работать они будут нормально.
... << RSDN@Home 1.2.0 alpha 4 rev. 1227 on Windows Vista 6.1.7100.0>>
Здравствуйте, OraStarter, Вы писали:
OS>Все верно. Я не знаю какие будут св-ва у экземпляра. Пример я привел, только чтобы показать ошибку не более того. А вообще я пишу дизайнер со своим ObjectInspector-ом в вебе поэтому и работаю через рефлексию.
О, вот прекрасный пример, почему надо правильно задавать вопросы. Если тебе для дизайнера, то ты полез не в ту степь. Для дизайнера надо не рефлекшеном пользоваться, а стандартной компонентной моделью. Соотв., в твоем примере можно сделать так:
var comp = new Myproperty2();
Console.WriteLine(TypeDescriptor.GetProperties(comp)[0].GetValue(comp));
using System;
using System.Reflection;
public class Myproperty1
{
private string caption = "A Default caption 1";
public virtual string Caption
{
get
{
return caption;
}
set
{
if (caption != value)
{
caption = value;
}
}
}
}
public class Myproperty2 : Myproperty1
{
private string caption2 = "A Default caption 2";
public override string Caption
{
set
{
if (caption2 != value)
{
caption2 = value;
}
}
}
}
namespace ConsoleApplication7
{
class Program
{
public static int Main()
{
Myproperty2 myproperty2 = new Myproperty2();
Type t = myproperty2.GetType();
do {
PropertyInfo propertyInfo = t.GetProperty("Caption");
if (propertyInfo == null)
break;
MethodInfo methodInfo = propertyInfo.GetGetMethod();
if (methodInfo != null)
{
Console.WriteLine("getter is: {0}", methodInfo);
object value = propertyInfo.GetValue(myproperty2, null);
Console.WriteLine(value);
break;
}
t = t.BaseType;
} while (t != null);
return 0;
}
}
}
ВВ>Вообще ответ в стиле:
ВВ>The Caption property on the class Myproperty2 does not have a Get method.
ВВ>Using reflection is not like using a general purpose object-oriented language, which has all kinds of rules for how to infer what you mean when you obviously don't mean what you say. When using reflection, you have to take the actual structure of the code into account.
ВВ>Мне кажется лапшой. Причем полной Вообще-то мы "имеем" в виду структуру кода как бы и также имеем в виду, что по умолчанию рефлекшин должен извлекать информацию обо всех мемберах, включая тех которые унаследованы — причем так и происходит, за исключением конкретного случая. Я уже говорил — описанное поведение логично для DeclaredOnly, но без него — нелогично совсем. ВВ>Товарищи же пытаются объяснить проблему в стиле, что рефлекшин, видите ли, это такая особая штука, с такими особыми правилами, нужно брать в расчет "структуру кода" и бла-бла-бла. Ты их спроси лучше, почему когда речь идет о перегрузке методов нужно брать в расчет одну структуру кода, а при перегрузке свойств — какую-то, видимо, совсем другую?
Здравствуйте, OraStarter, Вы писали:
Ovl>>рефлекшион обязателен? нельзя статикой обойтись?
OS>Нет, это я как пример ошибки показал. У меня класс работает с неизвестным обьектом...
Ну если надо просто задачу решить, то можно и просто в лоб:
Type t = myproperty2.GetType();
PropertyInfo propertyInfo = null;
while (t != null)
{
propertyInfo = t.GetProperty("Caption");
if (propertyInfo != null && propertyInfo.CanRead)
break;
t = t.BaseType;
}
Хотя, конечно, грустное поведение какое-то у GetProperty.
Более красивый по сравнению с вытаскиванием get_Caption?
Возможно, такого способа и нет. Binder в данном случае не поможет.
Вообще ИМХО не самое логичное поведение, разумнее было бы вести себя так при установленном флаге DeclaredOnly.
Здравствуйте, Воронков Василий, Вы писали:
AVK>>С тем, что приведенный код — корректен.
ВВ>Тогда мне непонятен критерий "корректности".
Критерий очень простой — если код не работает в ряде случаев, значит он неполностью корректен.
ВВ> Речь идет по сути о "хаке", призванном обойти весьма странное ограничение. Решение с GetMethod("get_Property"), если оно у тебя заработало, то будет работать всегда
Нет, всегда оно работать не будет. Ты же, надеюсь, понимаешь, что константа на конкретное свойство — это только пример и в реальном коде имена свойств будут браться из реальных произвольных типов, а не будут захардкожены?
ВВ>Это очень хорошо, что ты написал, что методы для свойств могут быть названы как угодно, но если они уже названы как get_XXX, set_XXX, то никто их менять не будет.
А кто тебе сказал, что автору нужен код, который будет работать исключительно со строго заданным и заранее известным набором свойств? Если это так, зачем там вообще рефлекшен тогда?
... << RSDN@Home 1.2.0 alpha 4 rev. 1227 on Windows Vista 6.1.7100.0>>
Здравствуйте, Ovl, Вы писали:
Ovl>Здравствуйте, OraStarter, Вы писали:
OS>>Гуру пришел с sql.ru (http://sql.ru/forum/actualthread.aspx?tid=672524) OS>>может подскажете более красивый способ? OS>>Спасибо
Ovl>рефлекшион обязателен? нельзя статикой обойтись?
Нет, это я как пример ошибки показал. У меня класс работает с неизвестным обьектом...
Здравствуйте, Воронков Василий, Вы писали:
OS>>Спасибо, интересны вариант ВВ>Ага, интересный. Вместо того, чтобы один раз вызвать метод с высокими накладными расходами будем дергать его несколько раз.
А это уже зависит от задачи. Может автору совсем не надо в цикле сто тысяч раз читать значение свойства, не правда ли?
Здравствуйте, MozgC, Вы писали:
OS>>>Спасибо, интересны вариант ВВ>>Ага, интересный. Вместо того, чтобы один раз вызвать метод с высокими накладными расходами будем дергать его несколько раз. MC>А это уже зависит от задачи. Может автору совсем не надо в цикле сто тысяч раз читать значение свойства, не правда ли?
Ну как бы недостатки очевидны, а польза? Вот вы видите в проекте код.
Вариант 1:
Type t = myproperty2.GetType();
PropertyInfo propertyInfo = null;
while (t != null)
{
propertyInfo = t.GetProperty("Caption");
if (propertyInfo != null && propertyInfo.CanRead)
break;
t = t.BaseType;
}
Вариант 2:
Type t = myproperty2.GetType();
var mi = t.GetMethod("get_Caption");
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Ну как бы недостатки очевидны, а польза? Вот вы видите в проекте код. ВВ>Какой понять легче?
Лично я бы использовал "get_Caption" и не заморачивался Просто человек привел альтернативное решение, что на мой взгляд в любом случае достойно уважения
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Ну как бы недостатки очевидны, а польза? Вот вы видите в проекте код. ВВ>Вариант 1:
ВВ>Вариант 2:
ВВ>Какой понять легче?
Как бы да. Второй конечно легче. Но если первый оформить в виде процедуры, а в комментарии написать причину такого варианта, то он тоже вполне понятный. Хотя оба варианта кривенькие. А ровный почему-то майкрософт не предусмотрел.
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Ну тогда весь код на МС++ некорректен, где пишут obj->get_Caption(), и все это дело еще как-то компилируется.
Ты не веришь в то, что геттер может называться по другому?
... << RSDN@Home 1.2.0 alpha 4 rev. 1227 on Windows Vista 6.1.7100.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Ты не веришь в то, что геттер может называться по другому?
Не верю. Т.к. если выйдет такое "обновление", то весь существующий код на фиг отвалится. Пример с МС++ я уже привел, где все эти кишки наружу торчат. Но ладно, МС++ немодный сейчас. Ну и так и компятор C# какое-нибудь
Здравствуйте, AndrewVK, Вы писали:
AVK>Компилятор шарпа и компилятор МС++ читают метаданные и используют токены реальных методов, а не тупо формируют строчку конкатенацией, так что работать они будут нормально.
Да, тем не менее в итоге-таки получается строчка, которая выглядит как "get_Caption". Разве нет?
Вот представим, выходит дотнет 4.0. Там метод стандартной библиотеки называется уже не get_Caption, а __get_Caption, ну неважно как. Вопрос: что произойдет с моим уже откомпилированным кодом?
У меня вот складывается впечатление, что наименования методов для свойств в стиле get_XXX и set_XXX — это уже стандарт дефакто.
ЗЫ.
Кстати, а что ты думаешь касательно затронутого в теме вопроса? Что существующая реализация RuntimeType.GetProperty с флажками Instance|Public не возвращает в данном случае информацию о сеттере свойства? Это логичное поведение или нет? Мне показалось, что похоже на бажок.
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Да, тем не менее в итоге-таки получается строчка, которая выглядит как "get_Caption". Разве нет?
Брр, чушь какую-то написал. Получается, конечно, не "строка", но прямой вызов метода, имеющего название get_Caption. Типа такого:
call instance void Test::get_Caption(string)
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Да, тем не менее в итоге-таки получается строчка, которая выглядит как "get_Caption". Разве нет?
Я тебе, кажется, наглядно продемонстрировал, что вместо get_Caption там легко может быть VoronkovSpecialFoo. И все будет работать.
ВВ>Вот представим, выходит дотнет 4.0. Там метод стандартной библиотеки называется уже не get_Caption, а __get_Caption, ну неважно как. Вопрос: что произойдет с моим уже откомпилированным кодом?
Перестанет работать.
ВВ>У меня вот складывается впечатление, что наименования методов для свойств в стиле get_XXX и set_XXX — это уже стандарт дефакто.
Нет никаких оснований на это рассчитывать.
ВВ>Кстати, а что ты думаешь касательно затронутого в теме вопроса? Что существующая реализация RuntimeType.GetProperty с флажками Instance|Public не возвращает в данном случае информацию о сеттере свойства? Это логичное поведение или нет?
ИМХО не очень.
... << RSDN@Home 1.2.0 alpha 4 rev. 1227 on Windows Vista 6.1.7100.0>>
Здравствуйте, AndrewVK, Вы писали:
ВВ>>Да, тем не менее в итоге-таки получается строчка, которая выглядит как "get_Caption". Разве нет? AVK>Я тебе, кажется, наглядно продемонстрировал, что вместо get_Caption там легко может быть VoronkovSpecialFoo. И все будет работать.
Я с этим и не спорю.
ВВ>>Вот представим, выходит дотнет 4.0. Там метод стандартной библиотеки называется уже не get_Caption, а __get_Caption, ну неважно как. Вопрос: что произойдет с моим уже откомпилированным кодом? AVK>Перестанет работать.
И как раз по этой причине я и не верю, что переименуют названия методов для свойств.
ВВ>>У меня вот складывается впечатление, что наименования методов для свойств в стиле get_XXX и set_XXX — это уже стандарт дефакто. AVK>Нет никаких оснований на это рассчитывать.
Ну смотри, вот сейчас, предположим, у меня в проекте есть "грязный хак", который получает значение свойства через "get_Caption".
Какая проблема у этого кода? Очень простая — если в будущей версии дотнета именование методов для свойств изменятся, то этот код перестанет работать. Но подождите, ведь если будут сделаны такие изменения в новой версии дотнета, то весь мой код по-любому перестанет под ней работать
ВВ>>Кстати, а что ты думаешь касательно затронутого в теме вопроса? Что существующая реализация RuntimeType.GetProperty с флажками Instance|Public не возвращает в данном случае информацию о сеттере свойства? Это логичное поведение или нет? AVK>ИМХО не очень.
Здравствуйте, Воронков Василий, Вы писали:
ВВ>>>Вот представим, выходит дотнет 4.0. Там метод стандартной библиотеки называется уже не get_Caption, а __get_Caption, ну неважно как. Вопрос: что произойдет с моим уже откомпилированным кодом? AVK>>Перестанет работать.
ВВ>И как раз по этой причине я и не верю
Это не вопрос веры.
AVK>>Нет никаких оснований на это рассчитывать.
ВВ>Ну смотри, вот сейчас, предположим, у меня в проекте есть "грязный хак", который получает значение свойства через "get_Caption". ВВ>Какая проблема у этого кода? Очень простая — если в будущей версии дотнета именование методов для свойств изменятся, то этот код перестанет работать.
При чем тут дотнет? Еще раз — рантайм не накладывает никаких ограничений на имена геттеров и сеттеров. Все целиком лежит на совести компилятора. Поэтому уже сейчас на такое можно натолкнуться легко — какой нибудь компилятор, отличный от МСных, динамически генерируемые сборки, сборки, обработанные обфускаторами и т.п.
ВВ> Но подождите, ведь если будут сделаны такие изменения в новой версии дотнета
Для этого не нужна новая версия дотнета, я тебе это наглядно продемонстрировал.
... << RSDN@Home 1.2.0 alpha 4 rev. 1227 on Windows Vista 6.1.7100.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>При чем тут дотнет? Еще раз — рантайм не накладывает никаких ограничений на имена геттеров и сеттеров. Все целиком лежит на совести компилятора. Поэтому уже сейчас на такое можно натолкнуться легко — какой нибудь компилятор, отличный от МСных, динамически генерируемые сборки, сборки, обработанные обфускаторами и т.п.
Я тебе объяснил, почему я считаю, что конвенция для именования таких методов не будет изменена. Потому что просто напросто весь существующий код отвалится. И это факт. Потому что компилятор раскрывает обращения к св-вам в вызовы методов. А это означает, что код t.GetMethod("get_Caption") несет в себе не больше проблем, чем s = Caption. На мой взгляд — это достаточно серьезная причина, чтобы ничего не менять.
С чем ты споришь — мне непонятно
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Я тебе объяснил, почему я считаю, что конвенция для именования таких методов не будет изменена. Потому что просто напросто весь существующий код отвалится.
Во-первых никакой конвенции нет, во-вторых существующие конечно менять не будут, а вот сборки, собранные другими компиляторами на практике могут попасться легко.
ВВ>С чем ты споришь — мне непонятно
С тем, что приведенный код — корректен.
... << RSDN@Home 1.2.0 alpha 4 rev. 1227 on Windows Vista 6.1.7100.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Во-первых никакой конвенции нет, во-вторых существующие конечно менять не будут, а вот сборки, собранные другими компиляторами на практике могут попасться легко.
Т.е. твой аргумент звучит как — а если бы все это было написано на Эрланге, то не работало бы?
ВВ>>С чем ты споришь — мне непонятно AVK>С тем, что приведенный код — корректен.
Тогда мне непонятен критерий "корректности". Речь идет по сути о "хаке", призванном обойти весьма странное ограничение. Решение с GetMethod("get_Property"), если оно у тебя заработало, то будет работать всегда, и данный код на мой взгляд никакой дополнительной угрозы в себе не несет.
Это очень хорошо, что ты написал, что методы для свойств могут быть названы как угодно, но если они уже названы как get_XXX, set_XXX, то никто их менять не будет.
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Тогда мне непонятен критерий "корректности". Речь идет по сути о "хаке", призванном обойти весьма странное ограничение. Решение с GetMethod("get_Property"), если оно у тебя заработало, то будет работать всегда, и данный код на мой взгляд никакой дополнительной угрозы в себе не несет.
Если оно заработало, то может не сработать например с генеренными emit-ом свойствами.
ВВ>Это очень хорошо, что ты написал, что методы для свойств могут быть названы как угодно, но если они уже названы как get_XXX, set_XXX, то никто их менять не будет.
Те что названы, может и не будут менять. Но кто даст гарантию?
А те что написаны не "get_XXX", а gef_xxx"? Мало ли, описался человек?
Здравствуйте, samius, Вы писали:
ВВ>>Тогда мне непонятен критерий "корректности". Речь идет по сути о "хаке", призванном обойти весьма странное ограничение. Решение с GetMethod("get_Property"), если оно у тебя заработало, то будет работать всегда, и данный код на мой взгляд никакой дополнительной угрозы в себе не несет. S>Если оно заработало, то может не сработать например с генеренными emit-ом свойствами.
Это как это? Оно или заработало или нет. Но тогда оно не сработает сразу, но ты все равно не получишь бомбу "замедленного действия".
Мне кажется, что мы обсуждали вызов конкретного свойства, а не разработку универсальной библиотеки для вызова любых свойств через рефлекшин.
ВВ>>Это очень хорошо, что ты написал, что методы для свойств могут быть названы как угодно, но если они уже названы как get_XXX, set_XXX, то никто их менять не будет. S>Те что названы, может и не будут менять. Но кто даст гарантию? S>А те что написаны не "get_XXX", а gef_xxx"? Мало ли, описался человек?
Читаем что я написал, еще раз:
методы для свойств могут быть названы как угодно, но если они уже названы как get_XXX, set_XXX, то никто их менять не будет.
Это утверждение верное.
Народ, вы поймите, что обращение к публичному свойству через get_XXX в данном случае полностью аналогично обращению к любому другому публичному методу через рефлекшин. Я приводил пример с МС++, где данная деталь реализации вообще никак не скрыта. Потому что:
— Метод можно назвать как угодно. Хоть SamiusSuperFoo
— Теоретически название метода может поменяться
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Мне кажется, что мы обсуждали вызов конкретного свойства, а не разработку универсальной библиотеки для вызова любых свойств через рефлекшин.
Разве? Ну ладно. Но даже в этом случае я бы не стал расчитывать что имя GetMethod-а свойства не изменится когда-нибудь.
ВВ>>>Это очень хорошо, что ты написал, что методы для свойств могут быть названы как угодно, но если они уже названы как get_XXX, set_XXX, то никто их менять не будет. S>>Те что названы, может и не будут менять. Но кто даст гарантию? S>>А те что написаны не "get_XXX", а gef_xxx"? Мало ли, описался человек?
ВВ>Читаем что я написал, еще раз:
ВВ>методы для свойств могут быть названы как угодно, но если они уже названы как get_XXX, set_XXX, то никто их менять не будет.
Вообще-то названия этих методов явно не указываются, а шлепает их компилятор. Вот перепишут MS компилятор шарпа и будут все GetMethod-ы называться "gXXX"! Скорее всего это не произойдет, но все же.
GetGetMethod отвечает за выдачу связанного со свойством метода, как бы он не назывался. Потому предпочтительнее.
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Мне кажется, что мы обсуждали вызов конкретного свойства, а не разработку универсальной библиотеки для вызова любых свойств через рефлекшин.
А тебе, случаем, не кажется, что вызов конкретного свойства через рефлекшен — безумие?
... << RSDN@Home 1.2.0 alpha 4 rev. 1227 on Windows Vista 6.1.7100.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>А тебе, случаем, не кажется, что вызов конкретного свойства через рефлекшен — безумие?
Лично мне не кажется. Автор же написал что у него класс работает с заранее неизвестным объектом. А еще может модификаторы доступа на тех классах мешают обратиться к свойствам или может в рантайме создаются типы и надо к их свойствам обращаться.
Здравствуйте, MozgC, Вы писали: MC>Лично мне не кажется. Автор же написал что у него класс работает с заранее неизвестным объектом. А еще может модификаторы доступа на тех классах мешают обратиться к свойствам или может в рантайме создаются типы и надо к их свойствам обращаться.
Все верно. Я не знаю какие будут св-ва у экземпляра. Пример я привел, только чтобы показать ошибку не более того. А вообще я пишу дизайнер со своим ObjectInspector-ом в вебе поэтому и работаю через рефлексию. По ошибке: создал на мс коннекте ченжреквест, может пофиксят, а может пошлют
Всем еще раз спасибо. Не шуточная борьба завязалась. Интересно почитать
Здравствуйте, AndrewVK, Вы писали:
AVK>А тебе, случаем, не кажется, что вызов конкретного свойства через рефлекшен — безумие?
Если свойство — internal, или же нам нужно вызвать его реализацию в супер-базовом классе, что шарп явно сделать не позволяет, то нет, не безумие.
А тебе не кажется, что обсуждаемая здесь проблема не столь уж и часто встречается на практике? Я, к примеру, за все время ни разу с подобным поведением не сталкивался.
Здравствуйте, AndrewVK, Вы писали:
AVK>Нет, всегда оно работать не будет. Ты же, надеюсь, понимаешь, что константа на конкретное свойство — это только пример и в реальном коде имена свойств будут браться из реальных произвольных типов, а не будут захардкожены?
Не, ну говорили-то мы о примере. Никакая конкретная задача здесь не обсуждается. В реальном коде будет и задача другая и решение, возможно, тоже.
ВВ>>Это очень хорошо, что ты написал, что методы для свойств могут быть названы как угодно, но если они уже названы как get_XXX, set_XXX, то никто их менять не будет.
AVK>А кто тебе сказал, что автору нужен код, который будет работать исключительно со строго заданным и заранее известным набором свойств?
А что нужно автору? Я вот не знаю
Знаю только, что у описанной здесь проблемы однозначно красивого решения нет. То, что здесь предложили с базовым клаccом потенциально несет в себе другие проблемы — и придется писать кучу кода, чтобы их обойти.
Вот, к примеру, в наш код передали класс, который перекрывает один из методов виртуального св-ва и изменяет логику. Очевидно это сделано для изменения поведения свойства. Изменим немножко код по ссылке:
using System;
using System.Reflection;
using System.Linq;
using System.Diagnostics;
public class Myproperty1
{
private string caption = "A Default caption";
public virtual string Caption {
get {
return"This is not a caption";
}
set {
if (caption != value) {
caption = value;
}
}
}
}
public class Myproperty2 : Myproperty1
{
private string caption2 = "A Default caption";
public override string Caption {
set {
if (caption2 != value) {
caption2 = value;
}
}
}
}
namespace ConsoleApplication7
{
class Program
{
public static void Main()
{
Myproperty2 myproperty2 = new Myproperty2();
var type = myproperty2.GetType();
var pi = type.BaseType.GetProperty("Caption");
var res = pi.GetValue(myproperty2, null);
Console.WriteLine(res);
}
}
}
Вывод:
> "C:\temp\bin\GetGetMethod_bug.exe"
This is not a caption
> Process Exit Code: 0
> Time Taken: 00:00
Т.е. этот вариант изначально некорректно работает Придется усложнять логику, держать два варианта проперти-инфо для вызова или как-то так и так далее.
Если у тебя есть альтернативное решение — предлагай. А то критиковать-то все могут
AVK>Если это так, зачем там вообще рефлекшен тогда?
Ну я вполне могу представить зачем нужен рефлекшин в таком случае. По крайней мере пример из реальной жизни придумать вполне можно
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Если свойство — internal, или же нам нужно вызвать его реализацию в супер-базовом классе, что шарп явно сделать не позволяет, то нет, не безумие.
Автор достаточно ясно выразился, чтобы ты продолжал фантазировать.
... << RSDN@Home 1.2.0 alpha 4 rev. 1227 on Windows Vista 6.1.7100.0>>
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Не, ну говорили-то мы о примере.
А, ну конечно, делать мне нечего, бесполезный код обсуждать. Все что я говорил, я говорил в контексте заданного автором вопроса, а не абстрактно.
AVK>>А кто тебе сказал, что автору нужен код, который будет работать исключительно со строго заданным и заранее известным набором свойств?
ВВ>А что нужно автору? Я вот не знаю
Так спроси. Впрочем, он уже ответил.
ВВ>Знаю только, что у описанной здесь проблемы однозначно красивого решения нет. То, что здесь предложили с базовым клаccом потенциально несет в себе другие проблемы — и придется писать кучу кода, чтобы их обойти.
Лучше некрасивый и корректно работающий код, нежели некрасивый и работающий некорректно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1227 on Windows Vista 6.1.7100.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>О, вот прекрасный пример, почему надо правильно задавать вопросы. Если тебе для дизайнера, то ты полез не в ту степь. Для дизайнера надо не рефлекшеном пользоваться, а стандартной компонентной моделью. Соотв., в твоем примере можно сделать так: AVK>
AVK>var comp = new Myproperty2();
AVK>Console.WriteLine(TypeDescriptor.GetProperties(comp)[0].GetValue(comp));
AVK>
AVK>P.S. На будущее — http://rsdn.ru/Info/Howtoask.xml
Больше спасибо, сегодня попробую... А чем это отличается от рефлексии? Как при этом получаются данные?
Спасибо.
Здравствуйте, <Аноним>, Вы писали:
А>Больше спасибо, сегодня попробую... А чем это отличается от рефлексии?
Уровень абстракции выше.
А> Как при этом получаются данные?
В основном конечно с помощью рефлексии, но там много всяких дополнительных моментов — специальные атрибуты, TypeConverter, ICustomTypeDescriptor и т.п.
... << RSDN@Home 1.2.0 alpha 4 rev. 1227 on Windows Vista 6.1.7100.0>>
Правда не уверен. Но нужно расматривать гетеры и сетеры с позиций других языков.
Поэтому надежнее добираться через методы PropertyInfo GetGetMethod() GetSetMethod()
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S>Правда не уверен. Но нужно расматривать гетеры и сетеры с позиций других языков. S>Поэтому надежнее добираться через методы PropertyInfo GetGetMethod() GetSetMethod()
Это я понимаю. Тут речь идет о том, что в МСИЛе нет такой специальной команды как call property. Поэтому если жизнь прижала — то нет ничего страшного в том, чтобы вызвать конкретный метод свойства напрямую. Поэтому что изменение имен методов свойств по сути равноценно изменению имени публичного метода, т.е. все клиенты по любому отваливаются.
The Caption property on the class Myproperty2 does not have a Get method.
Using reflection is not like using a general purpose object-oriented language, which has all kinds of rules for how to infer what you mean when you obviously don't mean what you say. When using reflection, you have to take the actual structure of the code into account.
Мне кажется лапшой. Причем полной Вообще-то мы "имеем" в виду структуру кода как бы и также имеем в виду, что по умолчанию рефлекшин должен извлекать информацию обо всех мемберах, включая тех которые унаследованы — причем так и происходит, за исключением конкретного случая. Я уже говорил — описанное поведение логично для DeclaredOnly, но без него — нелогично совсем.
Товарищи же пытаются объяснить проблему в стиле, что рефлекшин, видите ли, это такая особая штука, с такими особыми правилами, нужно брать в расчет "структуру кода" и бла-бла-бла. Ты их спроси лучше, почему когда речь идет о перегрузке методов нужно брать в расчет одну структуру кода, а при перегрузке свойств — какую-то, видимо, совсем другую?
Понятно. Но вообще в таком виде пример некорректен. Нет никакой гарантии, что мы достанем то же самое, свойство выполнив GetProperty("Caption") — hidebyname еще никто не отменял
Полноценное решение с использованием данного подхода должно все это учитывать.