Почему Convert.ChangeType не может конвертировать из char в double (или float)

202
18 июля 2018, 21:10

У меня есть такой метод:

    public static T To<T>(this char o)
        where T : struct
    {
        return (T)Convert.ChangeType(o, typeof(T));
    }

Если я на месте T стоит double (или float), то выдается InvalidCastException с текстом вроде System.InvalidCastException: Недопустимое приведение "Char" к "Double". Ну что не так с double? Тип явно больше char. Сейчас этот метод выглядит так:

public static T To<T>(this char o)
        where T : struct
    {
        var obj = Convert.ChangeType(o, typeof(int));
        return (T)Convert.ChangeType(obj, typeof(T));
    }

Сам вопрос - в заголовке. Это как-то объясняется где-нибудь с точки зрения логики? Я ответа не нашел.

Answer 1

Метод Convert.ChangeType внутри себя пытается привести аргумент к IConvertible и вызвать соответствующий метод.

Для случая с Char, будет вызываться его метод .ToDouble

/// <internalonly/>
double IConvertible.ToDouble(IFormatProvider provider) {
    throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "Char", "Double"));
}

В котором явно бросается исключение.

Почему метод .ToDouble не поддерживается?

Не только этот метод. .ToBoolean, .ToDateTime, .ToDecimal и .ToSingle тоже не поддерживаются, все они бросают InvalidCastException так же как и .ToDouble.

В этом случае дизайн .NET пытается уберечь вас от проблем. Преобразование char в целые типы имеет смысл, вы можете посмотреть на таблицы Unicode и посчитать количество codepoint. Но что должно означать преобразование в Boolean? Какой из Unicode code point будет True? Как символ вообще может быть дробным значением? Нет половинных или четвертных codepoint.

перевод ответа @HansPassant

Стоит так же отметить, что тип char может быть неявно преобразован в тип ushort, int, uint, long, ulong, float, double или decimal.

То есть следующий код отработает без ошибок:

char c = 'c';
double a = (double)c;
double b = c;
READ ALSO
Редактирование datagrid wpf

Редактирование datagrid wpf

чувствую себя совсем тупымне могу сделать редактируемую таблицу

203
Конструктор делегата

Конструктор делегата

Подскажите, пожалуйста, почему при объявлении делегата не нужно вызывать его конструктор с помощью ключевого слова new?

186
Получить доступ к файлу, в который постоянно записываются данные

Получить доступ к файлу, в который постоянно записываются данные

Привет) Возникла проблема: Необходимо каждые N минут (при событии OnTimerTick) отправлять лог файл (txt) на FTP сервер

242
Как работать с файлами в Unity на MacOs и Windows

Как работать с файлами в Unity на MacOs и Windows

Мне необходимо, в выбранной пользователем папке, изменять и переименовывать файлыЯ нашел ассет под unity, рисующий диалоговые окна под windows...

179