在非静态方法中,我可以使用this.GetType()
并且它将返回Type
。如何通过Type
静态方法获得相同的信息?当然,我不能只写,typeof(ThisTypeName)
因为ThisTypeName
仅在运行时才知道。谢谢!
在非静态方法中,我可以使用this.GetType()
并且它将返回Type
。如何通过Type
静态方法获得相同的信息?当然,我不能只写,typeof(ThisTypeName)
因为ThisTypeName
仅在运行时才知道。谢谢!
Answers:
如果您要寻找与this.GetType()
静态方法等效的1衬管,请尝试以下方法。
Type t = MethodBase.GetCurrentMethod().DeclaringType
尽管这可能比仅使用更昂贵typeof(TheTypeName)
。
typeof(TheTypeName)
无论如何,一个好的重构工具应该可以解决。
还有一些其他答案尚未完全弄清楚,这与您只在执行时可用的类型的想法有关。
如果使用派生类型执行静态成员,则在二进制文件中将省略实类型名称。因此,例如,编译以下代码:
UnicodeEncoding.GetEncoding(0);
现在在其上使用ildasm ...您将看到发出的呼叫如下:
IL_0002: call class [mscorlib]System.Text.Encoding
[mscorlib]System.Text.Encoding::GetEncoding(int32)
编译器已解决了对的调用Encoding.GetEncoding
-没有UnicodeEncoding
剩余痕迹。恐怕这会使您对“当前类型”的想法变得荒谬。
另一种解决方案是使用自引用类型
//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);
}
}
然后在继承它的类中,创建一个自引用类型:
public class Child: Parent<Child>
{
}
现在,Parent中的调用类型typeof(TSelfReferenceType)将获得并返回调用者的Type,而无需实例。
Child.GetType();
-抢
您不能this
在静态方法中使用,因此不可能直接使用。但是,如果您需要某种对象的类型,只需对其进行调用GetType
并将this
实例作为必须传递的参数即可,例如:
public class Car {
public static void Drive(Car c) {
Console.WriteLine("Driving a {0}", c.GetType());
}
}
但是,这似乎是一个糟糕的设计。您确定您确实需要在其自己的静态方法中获取实例本身的类型吗?这似乎有些奇怪。为什么不只使用实例方法呢?
public class Car {
public void Drive() { // Remove parameter; doesn't need to be static.
Console.WriteLine("Driving a {0}", this.GetType());
}
}
我不明白为什么您不能使用typeof(ThisTypeName)。如果这是非泛型类型,则应该可以使用:
class Foo {
static void Method1 () {
Type t = typeof (Foo); // Can just hard code this
}
}
如果是通用类型,则:
class Foo<T> {
static void Method1 () {
Type t = typeof (Foo<T>);
}
}
我在这里错过明显的东西吗?
当成员是静态成员时,您将始终知道它在运行时属于哪种类型。在这种情况下:
class A
{
public static int GetInt(){}
}
class B : A {}
您无法致电(编辑:显然,您可以,请参阅下面的评论,但您仍会致电A):
B.GetInt();
因为成员是静态的,所以它在继承方案中不起作用。因此,您始终知道类型是A。
就我的目的而言,我喜欢@ T-moty的想法。即使我使用“自我引用类型”信息已有多年,但以后很难再引用基类。
例如(使用上面的@Rob Leclerc示例):
public class ChildA: Parent<ChildA>
{
}
public class ChildB: Parent<ChildB>
{
}
例如,使用这种模式可能会充满挑战。如何从函数调用中返回基类?
public Parent<???> GetParent() {}
或何时进行类型转换?
var c = (Parent<???>) GetSomeParent();
因此,我尽量避免使用它,并在必要时使用它。如果必须的话,我建议您遵循以下模式:
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的建议可能是正确的方法。
但是,仅在基类在调用堆栈中不包含任何实例构造函数的情况下,才使用@ 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;
}