C#静态 "this"

16

在C#静态方法中,有没有一种方法可以引用定义该方法的类型?

在实例方法中,您可以通过以下方式确定类型:

public void Foo()
{
    Type type = this.GetType();
}

在静态方法中会是什么样子?

public static void Bar()
{
    Type type = ....?
}

更新:抱歉,需要澄清一下:我知道typeof(...)功能。我正在寻找一个可以在不显式引用类名的情况下给出类型的关键字或代码。

更新:除了Developer Art的答案可以完全满足我的需求外,还有更简单的方法吗?


1
为什么你想做这个?一旦得到了这个Type对象,你打算用它做什么? - AakashM
代码背后的意图是什么?在静态方法中你到底要用类型信息来干嘛? - Yves M.
2
@Yves:这与地狱无关。我只需要Type对象将其作为参数传递给给定的方法。为什么不能在静态方法中使用Type?Type既不是状态,也不以任何其他方式特定于实例。 - chiccodoro
@AakashM:非常有趣的链接!但它并不是重复的,因为我刚刚描述的是我提问背后的意图,而不是我的问题。;-) - chiccodoro
我认为这是一个非常有趣的问题。我的兴趣与派生类调用静态方法并且您想要获取该派生类的类型有关。在实例方法中,简单的this.GetType()将给您想要的结果。但在静态方法中,我不确定是否有明确的方法来实现相同的效果。C#7的计划中有一些有趣的讨论,但我不确定这将如何发展。有什么想法吗? - Eniola
显示剩余2条评论
6个回答

24

在这里:

public static void Bar()
{
  Type type = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType;
}

编辑:已更新以更正错误 - DeclaringType 是一个属性。


1
尽管这种方法是通用的,但它比简单的静态'typeof(ClassName)'更昂贵。 - Paul Ruane
11
作者显然对获取类型感兴趣,而不明确指定其名称。 - user151323
1
这需要一个 [MethodImpl(MethodImplOptions.NoInlining)] 修饰符来防止获取错误的方法吗? - Ani
@Developer Art:没错,我就是对此感兴趣。这个解决方案看起来既恰当又安全,比StackTrace的方法更稳妥。那么这是否意味着没有更简单的方式了?没有任何关键字可以用吗? - chiccodoro
有趣,但需要反射权限。这不仅在性能上代价高昂,而且在安全方面也是如此。在许多情况下,这两个问题可能根本不是问题,但保持警惕以了解阻止通用性的因素是很好的。在我的情况下,我最终复制了类名。复制通常是不好的,但一切都是妥协,不是吗? - Stéphane Gourichon
显示剩余2条评论

13
public class Foo {
   public static void Bar() {
      Type type = typeof(Foo);
   }
}

你也可以使用堆栈跟踪

public class Foo {
   public static void Bar() {
        Type type = new StackTrace().GetFrame(0).GetMethod().DeclaringType;
   }
}

1
@m0sa - 我曾经看到过优化器从堆栈跟踪中省略条目的情况,如果发生这种情况,第二种方法将无法工作。更多信息请参见此处:http://blogs.msdn.com/b/jmstall/archive/2005/03/20/399287.aspx - Steve Townsend
右侧清晰标识了一切... 如果其意图明确,var 就不会被滥用。4行代码而非1行可能被视为滥用... 但是 var 滥用?几乎不可能。 - WernerCD
@m0sa - 我们团队中有人使用这种方式来识别类型,我通过艰难的方式发现了这一点。在调试模式下可以工作,但在发布模式下无法正常工作。 - Steve Townsend

4
class ClassA
{
    public static void Bar()
    {
        Type t = typeof(ClassA);
    }
}

显然,我知道。

2
为什么不使用 typeof
public class Foo
{
  public static void Bar()
  {
    Type type = typeof(Foo);
  }
}

或者像开发人员Art建议的那样,您可以使用反射来实现,但速度会较慢。

using System.Reflection;
public class Foo
{
  public static void Bar()
  {
    Type type = MethodBase.GetCurrentMethod().DeclaringType();
  }
}

1

你可以使用

 Type t = typeof ( Program );

使用堆栈跟踪的一种非常特殊的方法是,获取最后一个框架的类型...

1

这有点复杂,但我认为你也可以采用单例模式的路线。

public class Foo
{
    private static Foo _Instance = new Foo();
    public static Type Bar()
    {
        return _Instance.GetType();
    }
}

嗨Steven,如果我创建了一个私有静态字段,该字段明确引用封闭类型,那么我更愿意使用private static Type _thisType = typeof(Foo); - chiccodoro
这也可以 :) 我只是提供了一些替代方法。如果再次出现需要静态版本的“this”的情况,那么这种方法就可以实现...如果类型是你所需要的全部内容,那么任何这些方法都可以很好地满足你的需求。 - Steven
嗨,史蒂文,抱歉,我没有仔细阅读你的代码,没有意识到你的Bar()方法确切地做到了这一点,只提供了类型。我以为那是“我的”静态方法,需要类型。 - chiccodoro
我的“建议”甚至更简单。只需一行代码即可轻松复制和粘贴。如果您愿意,可以将其作为第二种变体并入您的答案中。 - chiccodoro
@chiccodoro - 我不认为我表达得很清楚,如果我含糊不清,请原谅。我不反对你所建议的更简单的方法,如果易于访问Type是你所需要的一切,那么静态 '_Instance' 可能就有点过头了。我只是根据问题标题提出这个想法的。 如果 你因其他原因需要"this"的静态等效物,那么拥有像静态 _Instance 这样的东西就可以提供给你... - Steven

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接