Obtenir le type dérivé de la méthode statique

2013-01-27 c# reflection types static

Je veux obtenir le type dérivé de la méthode statique.

Je veux faire quelque chose comme ça

void foo()
{
  this.getType();
}

mais en méthode statique

je le sais

MethodBase.GetCurrentMethod().DeclaringType

renvoie le type de base, mais j'ai besoin de dérivé.

Answers

En supposant que vous voulez dire que vous avez quelque chose comme ça

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

class MyDerivedClass : MyBaseClass
{
}

et voulez MyDerivedClass.DoSomething(); pour imprimer "MyDerivedClass" , alors la réponse est:

Il n'y a pas de solution à votre problème. Les méthodes statiques ne sont pas héritées comme les méthodes d'instance. Vous pouvez vous référer à DoSomething aide de MyBaseClass.DoSomething ou MyDerivedClass.DoSomething , mais les deux sont compilés en tant MyBaseClass.DoSomething à MyBaseClass.DoSomething . Il n'est pas possible de savoir qui a été utilisé dans le code source pour effectuer l'appel.

Je suppose que vous avez besoin de quelque chose comme ce scénario:

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 
{
}

Ce code renverra cependant

Base       
Base

Cela est dû au fait que l'appel de méthode statique est résolu au moment de la compilation comme un appel à la classe de base, qui le définit réellement, même s'il a été appelé à partir d'une classe dérivée. Les lignes

Base.StaticMethod();
Derived.StaticMethod();

génère l'IL suivant:

IL_0001:  call        Base.StaticMethod
IL_0006:  nop         
IL_0007:  call        Base.StaticMethod

En un mot, cela ne peut pas être fait.

7 ans et demi plus tard ...

Je voulais faire à peu près la même chose, c'est ainsi que j'ai trouvé cette question. Il existe une solution qui est proche de ce qui est demandé et PEUT être utile pour ceux qui recherchent cette question.

Je voulais une méthode statique qui retournerait une instance de la classe avec tous les paramètres de base définis pour moi. Les oeuvres suivantes:

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 };
}

C'est bien beau, mais je voulais mettre cette fonction SetFoo dans la classe de base pour que

  1. Je n'aurais pas à avoir autant de code répétitif et
  2. Pour vous assurer que tous les objets SetFoo ont SetFoo .

Tu ne peux pas faire:

    public abstract static BaseClass SetFoo;

parce que quelque chose de statique ne peut pas être abstrait. Vous ne pouvez pas non plus:

    public static BaseClass SetFoo => new BaseClass{ Foo = false };

car vous ne pouvez pas créer une classe abstraite.

Cependant, vous pouvez utiliser des génériques pour spécifier le type dérivé que vous souhaitez. Cela ressemblerait à ceci:

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 };
}

Ce n'est qu'un peu plus maladroit que ce que nous voulions vraiment (dérivé.StaticBase), mais c'est assez proche.

Related