Check if types are castable / subclasses

后端 未结 6 2244
执笔经年
执笔经年 2020-12-07 00:32

I have they type of two members as strings - and not as a Type instance. How can I check if the two types are castable? Let\'s say string one is \"System.Windows.Forms.Label

6条回答
  •  臣服心动
    2020-12-07 01:20

    It might seem like you should use Type.IsAssignableFrom but note carefully the documentation:

    public virtual bool IsAssignableFrom(Type c)

    true if c and the current [instance of] Type represent the same type, or if the current [instance of] Type is in the inheritance hierarchy of c, or if the current [instance of] Type is an interface that c implements, or if c is a generic type parameter and the current [instance of] Type represents one of the constraints of c. false if none of these conditions are true, or if c is a null reference (Nothing in Visual Basic).

    In particular:

    class Base { }
    clase NotABase { public static implicit operator Base(NotABase o) { // } }
    
    Console.WriteLine(typeof(Base).IsAssignableFrom(typeof(NotABase)));
    

    will print False on the console even though NotABases are implicitly castable to Bases. So, to handle casting, we could use reflection like so:

    static class TypeExtensions {
        public static bool IsCastableTo(this Type from, Type to) {
            if (to.IsAssignableFrom(from)) {
                return true;
            }
            return from.GetMethods(BindingFlags.Public | BindingFlags.Static)
                              .Any(
                                  m => m.ReturnType == to && 
                                       (m.Name == "op_Implicit" || 
                                        m.Name == "op_Explicit")
                              );
        }
    }
    

    Usage:

    Console.WriteLine(typeof(string).IsCastableTo(typeof(int))); // false
    Console.WriteLine(typeof(NotABase).IsCastableTo(typeof(Base))); // true
    

    And for your case

    // from is string representing type name, e.g. "System.Windows.Forms.Label"
    // to is string representing type name, e.g. "System.Windows.Forms.Control"
    Type fromType = Type.GetType(from);
    Type toType = Type.GetType(to);
    bool castable = from.IsCastableTo(to);
    

提交回复
热议问题