.NET:在其静态方法中确定“this”类的types

在一个非静态的方法,我可以使用this.GetType() ,它会返回Type 。 我怎样才能获得相同的Type在一个静态的方法? 当然,我不能只写typeof(ThisTypeName)因为ThisTypeName只在运行时才是已知的。 谢谢!

如果您正在寻找与静态方法的this.GetType()等效的1 this.GetType() ,请尝试以下操作。

 Type t = MethodBase.GetCurrentMethod().DeclaringType 

虽然这可能比仅使用typeof(TheTypeName)要昂贵得多。

还有一些其他的答案还没有完全弄清楚,哪一个和你的types的思想只有在执行时才有用。

如果使用派生types来执行静态成员,则在二进制文件中省略实际types名称。 所以例如,编译这个代码:

 UnicodeEncoding.GetEncoding(0); 

现在使用ildasm …你会看到这样的呼叫:

 IL_0002: call class [mscorlib]System.Text.Encoding [mscorlib]System.Text.Encoding::GetEncoding(int32) 

编译器已经解决了对Encoding.GetEncoding的调用 – 没有剩下UnicodeEncoding的痕迹。 恐怕,这使得你的“现有types”的想法是荒谬的。

另一个解决scheme是使用自适应types

 //My base class //I add a type to my base class use that in the static method to check the type of the caller. public class Parent<TSelfReferenceType> { public static Type GetType() { return typeof(TSelfReferenceType); } } 

然后在inheritance它的类中,我创build一个自引用types:

 public class Child: Parent<Child> { } 

现在Parent中的调用typestypeof(TSelfReferenceType)将获得并返callback用者的Type而不需要实例。

 Child.GetType(); 

-抢

你不能在静态方法中使用this ,所以这是不可能的。 但是,如果您需要某个对象的types,只需调用GetType并使this实例成为必须传递的参数,例如:

 public class Car { public static void Drive(Car c) { Console.WriteLine("Driving a {0}", c.GetType()); } } 

不过这似乎是一个糟糕的devise。 你确定你真的需要在自己的静态方法中获取实例本身的types吗? 这似乎有点奇怪。 为什么不使用实例方法?

 public class Car { public void Drive() { // Remove parameter; doesn't need to be static. Console.WriteLine("Driving a {0}", this.GetType()); } } 

我不明白你为什么不能使用typeof(ThisTypeName)。 如果这是一个非genericstypes,那么这应该工作:

 class Foo { static void Method1 () { Type t = typeof (Foo); // Can just hard code this } } 

如果它是一个genericstypes,那么:

 class Foo<T> { static void Method1 () { Type t = typeof (Foo<T>); } } 

我在这里错过了很明显的东西吗

当你的成员是静态的,你将永远知道它在运行时是什么types的。 在这种情况下:

 class A { public static int GetInt(){} } class B : A {} 

你不能打电话(编辑:显然,你可以看到下面的评论,但你仍然会打电话给A):

 B.GetInt(); 

因为成员是静态的,所以在inheritance场景中不起作用。 埃尔戈,你总是知道这个types是A.

为了我的目的,我喜欢@T-moty的想法。 尽pipe我多年来一直使用“自引用types”信息,但引用基类很难做到。

例如(使用上面的@Rob Leclerc例子):

 public class ChildA: Parent<ChildA> { } public class ChildB: Parent<ChildB> { } 

例如,使用这种模式可能是有挑战性的。 你如何从函数调用返回基类?

 public Parent<???> GetParent() {} 

或者当types铸造?

 var c = (Parent<???>) GetSomeParent(); 

所以,我尽量避免它,当我必须使用它。 如果你一定要,我build议你遵循这种模式:

 class BaseClass { // All non-derived class methods goes here... // For example: public int Id { get; private set; } public string Name { get; private set; } public void Run() {} } class BaseClass<TSelfReferenceType> : BaseClass { // All derived class methods goes here... // For example: public TSelfReferenceType Foo() {} public void Bar(TSelfRefenceType obj) {} } 

现在,您可以(更)轻松地使用BaseClass 。 但是,像我目前的情况一样,有时候不需要从基类中暴露派生类,使用@M-moty的build议可能是正确的方法。

但是,只要基类不包含调用堆栈中的任何实例构造函数,就只能使用@M-moty的代码。 不幸的是我的基类使用实例构造函数。

因此,这是我的扩展方法,考虑到基类的“实例”构造函数:

 public static class TypeExtensions { public static Type GetDrivedType(this Type type, int maxSearchDepth = 10) { if (maxSearchDepth < 0) throw new ArgumentOutOfRangeException(nameof(maxSearchDepth), "Must be greater than 0."); const int skipFrames = 2; // Skip the call to self, skip the call to the static Ctor. var stack = new StackTrace(); var maxCount = Math.Min(maxSearchDepth + skipFrames + 1, stack.FrameCount); var frame = skipFrames; // Skip all the base class 'instance' ctor calls. // while (frame < maxCount) { var method = stack.GetFrame(frame).GetMethod(); var declaringType = method.DeclaringType; if (type.IsAssignableFrom(declaringType)) return declaringType; frame++; } return null; } } 

编辑这个方法只有当你用可执行文件/库部署PDB文件时才有效,就像markmnl指出的那样。

否则将会是一个很大的问题:在开发中运行良好,但可能不在生产中。


实用程序方法,只需在代码的每个位置调用需要的方法即可:

 public static Type GetType() { var stack = new System.Diagnostics.StackTrace(); if (stack.FrameCount < 2) return null; return (stack.GetFrame(1).GetMethod() as System.Reflection.MethodInfo).DeclaringType; }