Как на самом деле использовать TypeConverter и чем он отличается от System.Преобразовать.ToXXX()



Я искал более интуитивный способ преобразования типов данных в C# (например, перечисление в строку), поэтому я наткнулся на класс TypeConverter. Я читал документацию о том, как создать его, и это кажется довольно простым, просто переопределите несколько методов из TypeConverter с некоторой пользовательской логикой преобразования и готово.



Тем не менее, я не смог понять, как на самом деле использовать этот конвертер теперь, когда я его создал. каждый ресурс, который я нашел, просто объясняет, как это сделать. создайте один, и единственная ссылка, которую я видел, чтобы действительно использовать его, украшает мой класс типа [TypeConverter(typeof(MyConverter))]. Проблема в том, что у меня на самом деле нет класса типа, мой тип im преобразования в/из перечисления и строки, так что я понятия не имею, где я должен поместить TypeConverter.

Гипотетически, если бы мой тип был пользовательским классом, и я поместил бы украшение только на класс, где он определен, как бы я тогда преобразовал тип? Я просто использую тип в качестве строки, где я хочу, и конвертер будет магически делать свою работу, не спрашивая, или мне нужно как-то подсказать ему. Существует ли область, в которой я могу использовать преобразователь типов, или он доступен везде, где есть тип?



Я ожидал, что это будет работать как система.Но, похоже, это не так.

833   2  
c#

2 ответов:

Перечисление по-прежнему является пользовательским типом и может иметь такие атрибуты, как [TypeConverter].

Только небольшое число API используют TypeConverter; в частности, это означает System.ComponentModel, что и приводит к таким вещам, как PropertyGrid, поэтому: вы не получаете его везде автоматически, но он все еще может быть полезен в некоторых случаях. Основной предполагаемый способ получения конвертера:

var conv = TypeDescriptor.GetConverter(obj);

, что позволяет ему работать с атрибутами (которые вы нашли), но также ICustomTypeDescriptor и TypeDescriptor, через TypeDescriptor.GetProvider / TypeDescriptor.AddProvider. Это очень запутанно. но гибкая модель для динамического описания данных.

В большинстве сценариев, однако, TypeConverter обычно не является способом реализации вещей. Как только рабочий пример:
using System;
using System.ComponentModel;
using System.Globalization;

static class P
{
    static void Main()
    {
        var foo = Foo.Gamma;
        var converter = TypeDescriptor.GetConverter(typeof(Foo));
        string s = converter.ConvertToString(foo);
        Console.WriteLine(s);
    }
}

[TypeConverter(typeof(FooConverter))]
public enum Foo
{
    Alpha, Beta, Gamma
}
class FooConverter : TypeConverter
{
    public override object ConvertTo(ITypeDescriptorContext context,
        CultureInfo culture, object value, Type destinationType)
    {
        // write it backwards, because: reasons
        if (destinationType == typeof(string)) {
            var s = value.ToString();
            char[] c = s.ToCharArray();
            Array.Reverse(c);
            return new string(c);
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }
}
Тем не менее, это, вероятно, имеет больше смысла, как отмечалось ранее, когда смешивается с такими вещами, как PropertyGrid или другими элементами пользовательского интерфейса.

Он очень отличается от методов на Convert.*, так как это не расширяемая модель. System.ComponentModel можно настроить во время выполнения и использовать с объектами, которые на уровне объекта (не уровень типа) опишите себя. Основное использование этого было для таких вещей, как DataTable, так что строка может действовать так, как будто она имеет свойства, названные для каждого столбца - через PropertyDescriptor, а не PropertyInfo (отражение).

Я не могу помочь с TypeConverter, но вы можете получить список имен из перечисления довольно прямо:

List<string> pageSizes = Enum.GetNames(typeof(PageSize)).ToList();

Чтобы получить значение enum из его имени / строкового представления:

this.PageSize = (PageSize)Enum.Parse(typeof(PageSize), "A4")

Comments

    Ничего не найдено.