Как получить экземпляр TypeConverter указанный в атрибуте
От: WareZzhKa  
Дата: 23.07.08 05:34
Оценка:
Ломаю голову уже несколько дней над следующей проблемой:
как мне получить экземпляр TypeConverter, указанный в атрибуте для поля или свойства класса:
class A
{
 [TypeConverter(EnumConverter1)]
 private int _a;

[TypeConverter(EnumConverter2)]
 a
 {
  get { return _a; }
  set { _a = value; }
 }
}

Как мне получить TypeConverter converter = экземпляр TypeConverter для "_a" и для "a"
Re: Как получить экземпляр TypeConverter указанный в атрибут
От: WareZzhKa  
Дата: 23.07.08 05:48
Оценка:
для свойства я нашел зацепку — TypeDescriptor.GetProperties(.. а потом TypeDescriptor.GetConverter(..
Но как быть с полем класса? как для него получить тот TypeConverter который указан в атрибуте?
Re: Как получить экземпляр TypeConverter указанный в атрибут
От: _FRED_ Черногория
Дата: 23.07.08 09:11
Оценка:
Здравствуйте, WareZzhKa, Вы писали:

WZK>как мне получить экземпляр TypeConverter, указанный в атрибуте для поля или свойства класса:


WZK>Как мне получить TypeConverter converter = экземпляр TypeConverter для "_a" и для "a"

Зачем? TypeConverter используется для работы с "компонентами", и то, как они устроены в языке (свойства, поля, что-то ещё) не важно. "Снаружи" надо всегда использовать "TypeDescriptor.GetProperties(.. а потом TypeDescriptor.GetConverter(..". И что бы получить конвертер для поля "_a" в вашем классе:
[c#]
class A
{
 [TypeConverter(EnumConverter1)]
 private int _a;

[TypeConverter(EnumConverter2)]
 a
 {
  get { return _a; }
  set { _a = value; }
 }
}
[/c#]
необходимо сделать так, что бы это поле было представлено соответствующим PropertyDescriptor в компонентной моделе класса.

Для этого есть несколько способов: например, можно определить для класса TypeConverter, в котором переопределить GetProperties (и GetPropertiesSupported).

Совсем другой, "кривой" способ — рефлекшен:
var field = typeof(A).GetField("_a", BindingFlags.Instance | BindingFlags.NonPublic);
var attr = (TypeConverterAttribute)Attribute.GetCustomAttribute(field, typeof(TypeConverterAttribute));
if(attr != null) {
  var converter = Activator.CreateInstance(Type.GetType(attr.ConverterTypeName));
}//if
Help will always be given at Hogwarts to those who ask for it.
Re[2]: Как получить экземпляр TypeConverter указанный в атри
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 23.07.08 09:41
Оценка:
Здравствуйте, WareZzhKa, Вы писали:

WZK>Но как быть с полем класса? как для него получить тот TypeConverter который указан в атрибуте?


Получаешь экземпляр TypeConverterAttribute, далее Type.GetType(attr.ConverterTypeName), далее Activator.CreateInstance().

Более хитрый код легко подсмотреть рефлектором:
public virtual TypeConverter Converter
{
    get
    {
        AttributeCollection attributes = Attributes;
        if (converter == null)
        {
            TypeConverterAttribute attribute = (TypeConverterAttribute) attributes[typeof(TypeConverterAttribute)];
            if ((attribute.ConverterTypeName != null) && (attribute.ConverterTypeName.Length > 0))
            {
                Type typeFromName = GetTypeFromName(attribute.ConverterTypeName);
                if ((typeFromName != null) && typeof(TypeConverter).IsAssignableFrom(typeFromName))
                    converter = (TypeConverter) CreateInstance(typeFromName);
            }
            if (converter == null)
                converter = TypeDescriptor.GetConverter(this.PropertyType);
        }
        return this.converter;
    }
}
... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[3]: Как получить экземпляр TypeConverter указанный в атри
От: WareZzhKa  
Дата: 24.07.08 04:56
Оценка:
Огромное спасибо за ответы. вобщем-то думал — реально просто самому получать тип конвертора из TypeConverterAttribute — но встает вопрос: создания самого конвертера:
converter = (TypeConverter) CreateInstance(typeFromName);

Код будет вывалить эксепшены — ведь некоторые конвертеры не имеют конструктор без параметров (например, EnumTypeConverter)! Мне вот поэтому и интересно как разрулить систуацию. Пытался прогами рефлекторами посмотреть как же получает конвертер метод GetConverter. чето — не получилось это сделать((( Или GetConverter ищет сначала конструктор без параметров, а потом конструктор с 1 параметром Type?
Re[4]: Как получить экземпляр TypeConverter указанный в атри
От: _FRED_ Черногория
Дата: 24.07.08 05:46
Оценка: 1 (1)
Здравствуйте, WareZzhKa, Вы писали:

WZK>Код будет вывалить эксепшены — ведь некоторые конвертеры не имеют конструктор без параметров (например, EnumTypeConverter)! Мне вот поэтому и интересно как разрулить систуацию. Пытался прогами рефлекторами посмотреть как же получает конвертер метод GetConverter. чето — не получилось это сделать((( Или GetConverter ищет сначала конструктор без параметров, а потом конструктор с 1 параметром Type?


При создании TypeConverter-а сначала ищется [открытый] конструктор с одним параметром типа Type. Если такого конструктора не оказалось, вызывается конструктор без параметров. За подробностями — в ReflectTypeDescriptionProvider. Впрочем, никто не мешает сделать свой ITypeDescriptionProvider под свои нужды.
Help will always be given at Hogwarts to those who ask for it.
Re[5]: Как получить экземпляр TypeConverter указанный в атри
От: _FRED_ Черногория
Дата: 24.07.08 05:58
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>За подробностями — в ReflectTypeDescriptionProvider.


Так как речь о конвертере не на типе, а на свойстве, то он создаётся в PropertyDescriptor-е. По тому же алгоритму: или через конструктор с типом, или через конструктор без параметров.
Help will always be given at Hogwarts to those who ask for it.
Re[4]: Как получить экземпляр TypeConverter указанный в атри
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 24.07.08 07:50
Оценка: 1 (1)
Здравствуйте, WareZzhKa, Вы писали:

WZK>Огромное спасибо за ответы. вобщем-то думал — реально просто самому получать тип конвертора из TypeConverterAttribute — но встает вопрос: создания самого конвертера:

WZK>
WZK>converter = (TypeConverter) CreateInstance(typeFromName);
WZK>


Скачай уже себе, что ли, рефлектор.

protected object CreateInstance(Type type)
{
    Type[] types = new Type[] { typeof(Type) };
    if (type.GetConstructor(types) != null)
        return TypeDescriptor.CreateInstance(null, type, types, new object[] { PropertyType });
    return TypeDescriptor.CreateInstance(null, type, null, null);
}
... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[5]: Как получить экземпляр TypeConverter указанный в атри
От: WareZzhKa  
Дата: 24.07.08 11:25
Оценка:
_FRED_ и AndrewVK Благодарю за подробные ответы))
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.