Как сказать, конвертируем ли Тип A неявно к Типу B

Учитывая Тип a и Тип b, как может, я, во времени выполнения, определяю, существует ли неявное преобразование от до b?

Если это не имеет смысла, рассмотрите следующий метод:

public PropertyInfo GetCompatibleProperty<T>(object instance, string propertyName)
{
   var property = instance.GetType().GetProperty(propertyName);

   bool isCompatibleProperty = !property.PropertyType.IsAssignableFrom(typeof(T));
   if (!isCompatibleProperty) throw new Exception("OH NOES!!!");

   return property;   
}

И вот код вызова, что я хочу работать:

// Since string.Length is an int property, and ints are convertible
// to double, this should work, but it doesn't. :-(
var property = GetCompatibleProperty<double>("someStringHere", "Length");
22
задан Judah Gabriel Himango 8 February 2010 в 19:45
поделиться

2 ответа

Обратите внимание, что IsAssignableFrom НЕ решает вашу проблему. Вы должны использовать Reflection вот так. Обратите внимание на явную необходимость обработки примитивных типов; эти списки соответствуют §6.1.2 (Неявные числовые преобразования) спецификации.

static class TypeExtensions { 
    static Dictionary<Type, List<Type>> dict = new Dictionary<Type, List<Type>>() {
        { typeof(decimal), new List<Type> { typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(char) } },
        { typeof(double), new List<Type> { typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(char), typeof(float) } },
        { typeof(float), new List<Type> { typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(char), typeof(float) } },
        { typeof(ulong), new List<Type> { typeof(byte), typeof(ushort), typeof(uint), typeof(char) } },
        { typeof(long), new List<Type> { typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(char) } },
        { typeof(uint), new List<Type> { typeof(byte), typeof(ushort), typeof(char) } },
        { typeof(int), new List<Type> { typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(char) } },
        { typeof(ushort), new List<Type> { typeof(byte), typeof(char) } },
        { typeof(short), new List<Type> { typeof(byte) } }
    };
    public static bool IsCastableTo(this Type from, Type to) { 
        if (to.IsAssignableFrom(from)) { 
            return true; 
        }
        if (dict.ContainsKey(to) && dict[to].Contains(from)) {
            return true;
        }
        bool castable = from.GetMethods(BindingFlags.Public | BindingFlags.Static) 
                        .Any( 
                            m => m.ReturnType == to &&  
                            (m.Name == "op_Implicit" ||  
                            m.Name == "op_Explicit")
                        ); 
        return castable; 
    } 
} 

Использование:

bool b = typeof(A).IsCastableTo(typeof(B));
25
ответ дан 29 November 2019 в 05:03
поделиться

Неявные преобразования необходимо будет рассмотреть:

  • Идентификационные данные
  • sbyte к короткому, международному, долго, плавают, дважды, или десятичное число
  • байт к короткому, ushort, интервалу, uint, долго, ulong, плаванию или десятичному числу
  • короткий к интервалу, долго, плаванию или десятичному числу
  • ushort к интервалу, uint, долго, ulong, плаванию или десятичному числу
  • интервал к длинному, плаванию или десятичному числу
  • uint к длинному, ulong, плаванию или десятичному числу
  • долго для плавания, дважды, или десятичное число
  • ulong для плавания, дважды, или десятичное число
  • символ к ushort, интервалу, uint, долго, ulong, плаванию или десятичному числу
  • плавание для удвоения
  • преобразование типов Nullable
  • Ссылочный тип для возражения
  • Производный класс против Класса базового класса
  • к реализованному интерфейсу
  • Интерфейс для базирования интерфейса
  • Массив для выстраивания, когда массивы имеют то же количество размеров, существует неявное преобразование от исходного типа элемента до целевого типа элемента, и исходный тип элемента и целевой тип элемента являются ссылочными типами
  • Тип массива к Системе. Массив
  • Тип массива к IList <> и его основные интерфейсы
  • тип Делегата к Системе. Делегат
  • преобразование Упаковки
  • Перечисление вводит к Системе. Перечисление
  • Определяемое пользователем преобразование (op_implicit)

я предполагаю, что вы ищете последнего. Необходимо будет записать что-то напоминающее компилятор для покрытия всех их. Известный та Система. Linq. Выражения. Выражение не делало попытку этого подвига.

5
ответ дан 29 November 2019 в 05:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: