我想知道是否有可能(甚至通过反射等类似)在被调用的基类静态方法中获得调用方派生类。
例如,我有一个定义了静态方法的基类:public MyBaseClass {
public static void MyBaseClassStaticMethod() { /** ... **/ }
}
和它的派生类:
public MyDerivedClass : MyBaseClass { }
然后我调用:
MyDerivedClass.MyBaseClassStaticMethod()
在方法MyBaseClassStaticMethod
内部,是否有可能知道哪个是调用方派生类型?
(即MyDerivedClass
)
我只需要一个字符串…
可以通过以下方式使用泛型来解决您的场景
public class BaseClass<TDerived> where TDerived : BaseClass<TDerived>
{
public static void LogCallerType()
{
Console.WriteLine(typeof(TDerived).Name);
}
}
public class FooClass : BaseClass<FooClass> { }
public class BooClass : BaseClass<BooClass> { }
class Program
{
static void Main(string[] args)
{
FooClass.LogCallerType();
BooClass.LogCallerType();
}
}
这将依次输出以下
1. FooClass
2. BooClass
不,这是不可能的——绝不可能。static
方法不是多态的,因此这个信息根本不存在。
考虑重新设计你的代码。
在编译时,编译器将MyDerivedClass
替换为实际声明静态方法的类,在您的示例中是MyBaseClass
。
所以即使在IL中你也看不到MyDerivedClass
。该信息仅在源代码中存在。
静态方法静态地绑定到某个类,并不真正参与继承链。因此,它不存在于派生类中。因此,静态方法并不知道它实际上是在派生类中使用的。
但是,您可以通过编译器技巧从派生类访问静态成员。在msdn论坛的这篇文章中,来自派生类的静态成员访问被转换为来自包含静态成员的基类的调用。所以MyDerivedClass.MyBaseClassStaticMethod
被翻译成MyBaseClass.MyBaseClassStaticMethod
。因此,MethodBase.GetCurrentMethod().DeclaringType
总是返回MyBaseClass
。
所以简而言之:不,不可能从静态成员中获得派生类型
首先,静态方法不能访问调用它的实例。静态方法不同于普通的类方法,因为它不能访问类实例的this引用。
如果您将'this'作为参数传递给静态方法,那么您可以尝试像下面这样强制转换它。假设您有许多想要测试的派生类。
public static void MyBaseClassStaticMethod(MyBaseClass callingInstance)
{
MyDerivedClass myDerivedClass = callingInstance as MyDerivedClass;
MyDerivedClass2 myDerivedClass2 = callingInstance as MyDerivedClass2;
MyDerivedClass3 myDerivedClass3 = callingInstance as MyDefivedClass3;
...
// test for which derived class is calling
if (myDerivedClass != null)
...
else if (myDerivedClass2 != null)
...
...
}