21

C# には、基本クラスの Product と派生クラスの Widget があります。

製品には、静的メソッド MyMethod() が含まれています。

静的メソッド Widget.MyMethod() から静的メソッド Product.MyMethod() を呼び出したい。

base キーワードはインスタンス メソッドでしか機能しないため、使用できません。

Product.MyMethod() を明示的に呼び出すことはできますが、後で Widget を別のクラスから派生するように変更する場合は、メソッドを修正する必要があります。

派生クラスの静的メソッドから基本クラスの静的メソッドを呼び出すことができる base に似た C# の構文はありますか?

4

9 に答える 9

21

staticメソッドは基本的に、オブジェクト指向の概念からフォールバックする方法です。結果として、それらは継承階層においてあまり柔軟ではなく、そのようなことを直接行うことはできません。

私が考えることができる最も近いものはusingディレクティブです。

using mybaseclass = Namespace.BaseClass;

class MyClass : mybaseclass {

  static void MyMethod() {  mybaseclass.BaseStaticMethod();  }

}
于 2009-03-02T17:27:35.807 に答える
4

リフレクションを使用して静的メソッドを呼び出すことは、インスタンスに null を渡すことを除いて、インスタンス メソッドを呼び出すこととまったく同じです。祖先で定義されているため、FlattenHierarchy が必要です。

var type = assy.GetType("MyNamespace.MyType");
MethodInfo mi = type.GetMethod("MyStaticMethod", 
  BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);
mi.Invoke(null, null);

さらに読んで考えてみると、回答した他の人たちと同じ質問をすることになります。なぜこのような静的メソッドを使用するのですか? 関数型プログラミングをしようとしていますか?もしそうなら、代わりにラムダ式を使用してみませんか? 状態を共有するポリモフィックな動作が必要な場合は、インスタンス メソッドの方が適しています。

于 2012-07-03T10:55:39.337 に答える
2

何よりもまず、クラスの親を変更することを心配している場合は、継承を間違っている可能性があります。継承は、単にコードの再利用を促進するのではなく、「is-a」関係を確立するために使用する必要があります。コードの再利用のみが必要な場合は、継承ではなく委譲の使用を検討してください。サブタイプとその親の間に中間タイプを導入できると思いますが、その可能性が私の設計を推進させます。

第 2 に、基本クラスの機能を使用する必要があるが、それを拡張し、かつユース ケースが静的メソッドを呼び出す場合は、機能を保持するために何らかの外部クラスを使用することを検討することをお勧めします。私の考えでは、この典型的なケースは Factory パターンです。ファクトリ パターンを実装する 1 つの方法は、クラスのインスタンスを構築するクラスの静的メソッドであるファクトリ メソッドを使用することです。通常、コンストラクターは保護されているため、ファクトリ メソッドが外部からクラスを構築する唯一の方法になります。

継承階層でファクトリ メソッドを再利用する方法の 1 つは、サブタイプのファクトリ メソッドから基本クラスのファクトリ メソッドを直接呼び出すのではなく、保護されたメソッドに共通コードを配置し、ファクトリ メソッドからそのメソッドを呼び出すことです。より良い実装では、同じ手法を使用するかもしれませんが、Factory メソッドを Factory クラスに移動し、おそらく初期化メソッドと組み合わせて、コンストラクター ロジック (現在はプライベートではなく内部) を使用してオブジェクトを作成します。継承している動作がクラスの外部にある場合 (復号化/検証など)、Factory 内で共有メソッド (または構成) を使用して、Factory メソッド間で再利用できるようにすることができます。

静的メソッドを使用する目的を知らなければ、正確な方向性を示すことは困難ですが、これが役立つことを願っています。

于 2013-01-07T14:08:41.423 に答える
0

とても簡単です。エイリアシングやリフレクションなどを使用するよりもはるかに簡単です。.NET、IDKの新しい追加で簡単になったかもしれませんが、これは完全に正常に機能します。インスタンスメソッドの場合と同様に、基本メソッドへのアクセスをbase使用する必要はありません。これはオプションであり、通常、継承クラスと基本クラスに同じ名前のメソッドがある場合に必要です。キーワードがなくても、base呼び出し元のクラスにあるかのように、基本クラスの静的メソッドにアクセスできます。これは、派生クラスの静的メソッドから基本静的メソッドを呼び出すときにのみテストしました。インスタンスメソッドから静的メソッドを呼び出す場合は、機能しない可能性があります。

public class BaseThings
{
    protected static void AssertPermissions()
    {
        //something
    }
}

public class Person:BaseThings
{
    public static void ValidatePerson(Person person)
    {
        //just call the base static method as if it were in this class.
        AssertPermissions();            
    }
}
于 2012-12-14T22:01:31.507 に答える
0

静的メソッドがインスタンス データを中継しないことを考慮すると、パラメーターなどに基づいて異なる動作をする静的な「MyMethod」が必要です。

あるクラスで定義された静的メソッドは、コードを順序付けするための手段に過ぎないことを思い出してください...しかし、そのメソッドが別の場所に配置されていても同じです...配置されているオブジェクトを中継しないためです。

編集:私はあなたの最善の選択は Product.MyMethod を明示的に使用することだと思います...あなたがそれを考えるなら...ウィジェットがその基本クラスを変更する可能性は低いはずです...そしてその場合、それはマイナーな変更ですコードで。

于 2009-03-02T17:31:29.603 に答える
0

静的メソッドは「クラスレベル」のメソッドです。これらは、特定のクラスのすべてのインスタンスに適用されるメソッドを意図しています。したがって、このメソッドの継承は意味がありません。クラスのインスタンスに適用する意味が変わってしまうからです。たとえば、製品のコレクション (ウィジェットの一部とそうでないもの) をループし、各製品で MyMethod を呼び出した場合、呼び出されたメソッドはクラスのインスタンスによって決定されます。これは、静的メソッドの目的に違反しています。

あなたの例では、 MyMethod が Product のすべてのインスタンスに適用されているようには見えないため、静的メソッドをまったく使用しないことで、よりきれいにしたいことができるでしょう。ただし、'IMyMethod' などのインターフェイス クラスを使用して、記述しているのと同じ効果を実現できます。このアプローチはまだ静的メソッドを使用していません。私は静的メソッドの必要性を見ていないと思います。そもそも静的メソッドを使用する理由は何ですか?

于 2009-03-02T23:05:33.857 に答える