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 NotABase
s are implicitly castable to Base
s. 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);
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…