C # TypeConverter.ConvertFrom () проблема - PullRequest
       18

C # TypeConverter.ConvertFrom () проблема

1 голос
/ 10 февраля 2011

У меня проблема со следующим кодом, который возвращает объект из строки:

[TypeConverter(typeof(MyConverter))]
public class MyClass
{
    public string s;
}

public class MyConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return (sourceType == typeof(string)) ? true : base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        if (value is string)
        {
            MyClass m = new MyClass();
            m.s = (string)value;
            return m;
        }

        return base.ConvertFrom(context, culture, value);
    }
}

Когда я пытаюсь использовать этот код:

string s_test = "test";

MyClass m_test;

m_test = (MyClass)Convert.ChangeType(s_test, typeof(MyClass));

Я получаю ошибкусообщение

Неправильное приведение из «System.String» к «MyClass».

Что не так в моем коде?Обратите внимание, что я должен использовать метод ConvertFrom () ...

Заранее благодарен за помощь.

Трассировка стека:

[InvalidCastException: Invalid cast from 'System.String' to 'MyClass'.]
   System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider) +9496632
   System.String.System.IConvertible.ToType(Type type, IFormatProvider provider) +8
   System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) +9531720
   System.Convert.ChangeType(Object value, Type conversionType) +32
   OrderController.Index() in [...].cs:70
   ... omitted for brevity ...

Ответы [ 5 ]

8 голосов
/ 10 февраля 2011

Вы ожидаете, что Convert.ChangeType будет использовать TypeConverter, если он есть - его нет. TypeConverter обычно используется вместе с TypeDescriptor (часто неявно в платформах пользовательского интерфейса).

3 голосов
/ 10 февраля 2011

Построение правильного ответа от Джона Скита, вам нужно использовать TypeDescriptor, чтобы сделать преобразование. Измените свой тестовый код с:

string s_test = "test";
MyClass m_test;
m_test = (MyClass)Convert.ChangeType(s_test, typeof(MyClass));

Кому:

string s_test = "test";
MyClass m_test;
m_test = (MyClass)TypeDescriptor.GetConverter(typeof(MyClass)).ConvertFromString(test);

и все должно быть хорошо.

3 голосов
/ 10 февраля 2011

У вас, кажется, впечатление, что Convert.ChangeType ищет TypeConverter. Это не так.

С MSDN doc : «Чтобы преобразование прошло успешно, значение должно реализовывать интерфейс IConvertible»

Поскольку System.String не реализует IConverter<MyClass>, вам не повезло (с классом Convert, в любом случае). Как сказал Скит (и MSDN) , вместо него используйте TypeDescriptor.

2 голосов
/ 21 июня 2012

(нашел эту ссылку при поиске ответа на похожий вопрос, поэтому публикуем лучший найденный ответ)

неявные и явные операторы, кажется, то, что вы хотите, TypeConverter не нужен

public class MyClass
{
    public string s;

    public static explicit operator MyClass(string s) {
        MyClass m = new MyClass();
        m.s = (string)value;
        return m;
    }
}

Что позволяет следующее: -

string s_test = "test";

MyClass m_test;

m_test = (MyClass)s_test;

Примечание: приведенное выше не проверено, но должно быть достаточно близко, чтобы дать необходимые подсказки.

0 голосов
/ 22 февраля 2012

Библиотека SixPack имеет класс TypeConverter , который поддерживает большинство методов преобразования .NET, включая TypeConverter. Поддерживаются следующие преобразования:

  • TypeConverter для типа источника
  • TypeConverter для типа назначения
  • C # явные и неявные операторы приведения
  • IConvertible

Существует также специальная обработка следующих типов

  • DBNull
  • Nullable
  • Enum
  • TimeSpan
...