从base的类静态方法获取派生类类型

我想从其基类​​的静态方法获取派生类的类型。

如何实现这一目标?

谢谢!

class BaseClass { static void Ping () { Type t = this.GetType(); // should be DerivedClass, but it is not possible with a static method } } class DerivedClass : BaseClass {} // somewhere in the code DerivedClass.Ping(); 

如果我没有弄错的话,为BaseClass.Ping()DerivedClass.Ping()发出的代码是相同的,所以使方法静态而不给它任何参数是行不通的。 尝试将类型作为参数传递或通过generics类型参数(您可以在其上强制执行inheritance约束)。

 class BaseClass { static void Ping() where T : BaseClass { Type t = typeof(T); } } 

你会这样称呼它:

 BaseClass.Ping(); 

这可以使用奇怪的重复模板模式轻松完成

 class BaseClass where T : BaseClass { static void SomeMethod() { var t = typeof(T); // gets type of derived class } } class DerivedClass : BaseClass {} 

调用方法:

 DerivedClass.SomeMethod(); 

此解决方案会增加少量样板开销,因为您必须使用派生类对基类进行模板化。

如果您的inheritance树有两个以上的级别,那么它也是限制性的。 在这种情况下,您必须选择是否通过模板参数或在其子项上强制使用静态方法的调用。

当然,通过模板我的意思是generics。

在类型上定义静态方法。 没有“这个”。 您需要将此实例方法改为:

 class BaseClass { public void Ping() { Type t = this.GetType(); // This will work, since "this" has meaning here... } 

然后你可以这样做:

 class DerivedClass : BaseClass {} DerivedClass instance = new DerivedClass(); instance.Ping(); 

简而言之,这就是我试图在这里回答的问题 。 它使用一个接口来统一所有派生类,并让它们从基类调用相同的静态方法而不传递Type。

 public interface IDerived { } public class BaseClass where T : IDerived { public static void Ping() { //here you have T = the derived type } } public class DerivedClass : BaseClass, IDerived { //with : BaseClass we are defining the T above } public class ExampleApp { public void Main() { //here we can call the BaseClass's static method through DerivedClass //and it will know what Type calls it DerivedClass.Ping(); } } 

只是一个猜测(没有测试)

 Type t = MethodBase.GetCurrentMethod().DeclaringType; 

从静态方法获取派生类是不可能的。 作为一个例子来说明原因,想象BaseClass有2个子类 – DerivedClass和AnotherDerivedClass – 应该返回哪一个? 与多态非静态方法不同,在基类上调用静态方法的派生类没有可能的关联 – 编译时类型和运行时类型与静态方法调用相同。

您可以使方法非静态,因此您可以通过多态获取正确的类型,或者在子类中创建静态方法“覆盖”,例如

 class DerivedClass : BaseClass { void Ping() { BaseClass.Ping(); // or alternatively BaseClass.Ping(Type.GetType("DerivedClass")); } } 

然后,您的客户端代码可以调用派生类中的方法,以明确指示它是否需要派生类版本。 如有必要,您还可以将DerivedClass类型作为参数传递给基类方法,以提供通过派生类调用该方法的上下文。

为什么不直接使用已有的方法?

如果你有

 class BaseClass {} partial class DerivedClass : BaseClass {} 

你可以看看

 DerivedClass.GetType().BaseType; 

我认为以下内容适用于本案例(以及SO上其他几个类似的案例)。 Perf不会太好,但如果这种情况不常见,那就不会有问题了。

创建一个堆栈跟踪并解析它以查找派生类。 在一般情况下,这不太可靠或甚至可能不起作用,但在特定情况下 ,如OP中的情况,我相信这将工作正常。 在Powershell中:

 $strace = (new-object diagnostics.stacktrace).tostring() # $frames = $strace -split " at " $typesFromFrames = $frames | select -skip 1| # skip blank line at the beginning % { ($_ -split "\(",2)[0]} | # Get rid of parameters string % {$_.substring(0,$_.lastindexof("."))} | # Get rid of method name $ {$_ -as [type]} # # In powershell a lot of the frames on the stack have private classes # So $typesFromFrames.count is quite a bit smaller than $frames.count # For the OP, I don't think this will be a problem because: # 1. PS isn't being used # 2. The derived class in the OP isn't private # (if it is then tweaks will be needed) # $derivedOnStack = $typesFromFrames | ? { $_.issubclassof( [BaseClass])} 

希望$ derivedOnStack中只有一个元素,但它将取决于应用程序的细节。 将需要一些实验。