.net - 如何判断类型 A 是否可隐式转换为类型 B

标签 .net reflection type-conversion implicit-conversion

给定类型 a 和类型 b,我如何在运行时确定是否存在从 a 到 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不能解决您的问题。你必须像这样使用反射。请注意处理原始类型的显式需求;这些列表符合规范的 §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));

关于.net - 如何判断类型 A 是否可隐式转换为类型 B,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2224266/

相关文章:

c# - 用数组名称包装序列化数组元素

.net - 你可以在没有办公室的情况下安装 Office 2007 PIA

c# - 在 COM 对象上使用反射调用方法

.NET 反射助手 API?

c - 从 c 中的 char* float

.net - 转换和拆箱有什么区别?

c# - 如何使用 C# 在标签上显示更新时间作为系统时间?

c# - 如何遍历对象的成员变量?

python - 如何将 Tensor 转换为 ndarray(内部含有对抗性图像的张量)

c - 在 C 中以位拆分 uint16_t