Учитывая Тип 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");
Обратите внимание, что 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));
Неявные преобразования необходимо будет рассмотреть:
я предполагаю, что вы ищете последнего. Необходимо будет записать что-то напоминающее компилятор для покрытия всех их. Известный та Система. Linq. Выражения. Выражение не делало попытку этого подвига.