10

静的メソッドから派生型を取得したい。

こんなことしたい

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

しかし静的メソッドでは

そんなこと知ってる

MethodBase.GetCurrentMethod().DeclaringType

基本タイプを返しますが、派生する必要があります。

4

3 に答える 3

13

あなたがこのようなものを持っていることを意味すると仮定します

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

class MyDerivedClass : MyBaseClass
{
}

MyDerivedClass.DoSomething();印刷したい"MyDerivedClass"場合、答えは次のとおりです。

あなたの問題に対する解決策はありません。静的メソッドは、インスタンスメソッドのように継承されません。またはをDoSomething使用して参照できますが、どちらもへの呼び出しとしてコンパイルされます。呼び出しを行うためにソースコードで使用されたものを見つけることはできません。MyBaseClass.DoSomethingMyDerivedClass.DoSomethingMyBaseClass.DoSomething

于 2013-01-26T22:51:03.500 に答える
11

このシナリオのようなものが必要だと思います。

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

一言で言えば、それはできません。

于 2013-01-26T22:54:11.107 に答える
2

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関数を基本クラスに入れて、

  1. 繰り返しの多いコードは必要ありません。
  2. すべてのBaseClassオブジェクトに。があることを確認しますSetFoo

できません:

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

これは、私たちが本当に望んでいたもの(derivated.StaticBase)よりも少し不格好ですが、かなり近いです。

于 2020-06-30T04:41:15.547 に答える