请考虑以下代码:
public static class ParentHelper {
public static string GetTypeString<T>(this T parent) where T : Parent {
return typeof(T).ToString();
}
}
public abstract class Parent {
public string GetMyType(bool withReflection) {
return withReflection
? typeof(ParentHelper)
.GetMethod("GetTypeString")
.MakeGenericMethod(GetType()).Invoke(null, new object[] { this }) as string
: this.GetTypeString();
}
}
public class Child : Parent {
}
void Main() {
Child child = new Child();
child.GetMyType(false).Dump(); // Parent
((Parent) child).GetMyType(false).Dump(); // Parent
child.GetMyType(true).Dump(); // Child
((Parent) child).GetMyType(true).Dump(); // Child
}
令我惊讶的是,GetMyType
方法会根据其调用GetTypeString
的方式返回不同的值(请参阅Main
方法中的注释)。
使用普通的GetTypeString
语法时,object.ExtensionMethod()
扩展方法是否有办法处理子类类型而不是父类?
请注意,这段代码是我可以放在一起的最小例子 - 我的用法完全不同(不返回类型,而是一个装饰子类的属性)。
答案 0 :(得分:3)
是的,您需要将typeof(T)
替换为parent.GetType()
,而不是。{/ p>
他们做不同的事情。
答案 1 :(得分:2)
this.GetTypeString();
已编译为ParentHelper.GetTypeString<Parent>()
,因为它是从Parent.GetMyType
传递的类型。
通常的解决方案 - 让Parent
通用其子代(也就是奇怪的递归模板),如:
public abstract class Parent<TChild> where TChild : Parent<TChild>
{
public string GetMyType()
{
return ((TChild)this).GetTypeString();
}
}
或者你可以使用类似于构造反射调用的GetType()
,但它会放弃一些编译类型的安全性。