C# 从静态方法获取派生类型

C# 从静态方法获取派生类型,c#,reflection,types,static,C#,Reflection,Types,Static,我想从静态方法中获取派生类型 我想做这样的事情 void foo() { this.getType(); } class MyBaseClass { public static void DoSomething() { Console.WriteLine(/* current class name */); } } class MyDerivedClass : MyBaseClass { } 但在静态方法中 我知道 MethodBase.GetC

我想从静态方法中获取派生类型

我想做这样的事情

void foo()
{
  this.getType();
}
class MyBaseClass
{
    public static void DoSomething()
    {
        Console.WriteLine(/* current class name */);
    }
}

class MyDerivedClass : MyBaseClass
{
}
但在静态方法中

我知道

MethodBase.GetCurrentMethod().DeclaringType

返回基类型,但我需要派生。

假设您的意思是这样的

void foo()
{
  this.getType();
}
class MyBaseClass
{
    public static void DoSomething()
    {
        Console.WriteLine(/* current class name */);
    }
}

class MyDerivedClass : MyBaseClass
{
}
想要
MyDerivedClass.DoSomething()
要打印“MyDerivedClass”,答案是:


你的问题没有解决办法。静态方法不像实例方法那样被继承。您可以使用
MyBaseClass.DoSomething
MyDerivedClass.DoSomething
引用
DoSomething
,但两者都是作为对
MyBaseClass.DoSomething
的调用编译的。无法找出在源代码中使用了哪些代码来进行调用。

我想您需要类似于此场景的内容:

void Main()
{
  Base.StaticMethod(); // should return "Base"
  Derived.StaticMethod();  // should return "Derived"
}


class Base
{
  public static void StaticMethod()
  {
    Console.WriteLine(MethodBase.GetCurrentMethod().DeclaringType.Name);
  }
}

class Derived: Base 
{
}
但是,此代码将返回

Base       
Base
这是因为静态方法调用在编译时被解析为对基类的调用,基类实际上定义了它,即使它是从派生类调用的。台词

Base.StaticMethod();
Derived.StaticMethod();
生成以下IL:

IL_0001:  call        Base.StaticMethod
IL_0006:  nop         
IL_0007:  call        Base.StaticMethod
总之,这是不可能的。

7年半后

我想做的和我发现这个问题的原因差不多。有一个解决方案接近于所要求的,并且可能对搜索此问题的其他人有用

我想要一个静态方法,它将返回一个类的实例,并为我设置所有的基本设置。以下工作:

void Main()
{
    ChildClassA cA = ChildClassA.SetFoo();
}

public abstract class BaseClass
{
    public bool Foo {get; set;}
}

public class ChildClassA : BaseClass
{
    public static ChildClassA SetFoo() => new ChildClassA{Foo = false};
}

public class ChildClassB : BaseClass
{
    public static ChildClassB SetFoo() => new ChildClassB { Foo = false };
}
这很好,但是我想把
SetFoo
函数放在基类中,这样

  • 我不需要有这么多重复的代码和
  • 确保所有基类对象都具有
    SetFoo
  • 你不能这样做:

        public abstract static BaseClass SetFoo;
    
        public static BaseClass SetFoo => new BaseClass{ Foo = false };
    
    因为静态的东西不可能是抽象的。你也不能这样做:

        public abstract static BaseClass SetFoo;
    
        public static BaseClass SetFoo => new BaseClass{ Foo = false };
    
    因为你不能新建一个抽象类

    但是,您可以使用泛型来指定所需的派生类型。看起来是这样的:

    void Main()
    {
        ChildClassA cA = BaseClass.SetFoo<ChildClassA>();
    }
    
    public abstract class BaseClass
    {
        public bool Foo {get; set;}
        
        public static T SetFoo<T>() where T:BaseClass, new() => new T{Foo = false };
    }
    
    public class ChildClassA : BaseClass
    {
        // You can leave this here if you still want to call ChildClassA.SetFoo();
        //public static ChildClassA SetFoo() => new ChildClassA{Foo = false};
    }
    
    public class ChildClassB : BaseClass
    {
        //Again, you can leave this for ChildClassB.SetFoo()--the compiler won't mind
        //public static ChildClassB SetFoo() => new ChildClassB { Foo = false };
    }
    
    void Main()
    {
    ChildClassA cA=BaseClass.SetFoo();
    }
    公共抽象类基类
    {
    公共bool Foo{get;set;}
    公共静态T SetFoo(),其中T:BaseClass,new()=>newt{Foo=false};
    }
    公共类ChildClassA:基类
    {
    //如果仍要调用ChildClassA.SetFoo(),则可以将其留在这里;
    //public static ChildClassA SetFoo()=>new ChildClassA{Foo=false};
    }
    公共类ChildClassB:基类
    {
    //同样,您可以将这个留给ChildClassB.SetFoo()--编译器不会介意的
    //public static ChildClassB SetFoo()=>new ChildClassB{Foo=false};
    }
    

    这只是比我们真正想要的(派生的.StaticBase)稍微笨拙一点,但它非常接近。

    你能给出一个更详细的例子吗?顺便说一句,“sth”不是一个英语单词,也不是“something”一词的公认缩写。我认为FxCop或ReSharper会抱怨,如果它捕捉到您在派生类上调用静态方法,比如“您确定您知道这里发生了什么吗?”因此,我可能应该使用泛型,并尝试获取typeof(T),或者您知道更好的方法吗?您可以将类型传递给方法:DoSomething(type-derivedStaticType)然后在DoSomething中使用这种类型(同时检查它是否确实派生自MyBaseClass)。在java中,你可以通过stacktrace黑客获得调用类,但我认为这在C中是不可能的。