-3

ここで静的メソッドとインスタンスメソッドについて読んだことがありますが、この特定の質問に答えるものはありません(緑かもしれません)。

いくつかのプロパティを持つクラスと、それらのプロパティを使用する必要があるそのクラスのメソッドがある場合、静的メソッドとインスタンス メソッドのどちらを使用する方がよいでしょうか?

IE

class Foo
{
    //properties
    bar1;
    bar2;

    //method
    sumbar1andbar2()
    {
        return bar1 + bar2;
    }
}

sumbar1andbar2 メソッドには、Foo クラスの両方のプロパティが存在する必要があります。クラスのメンバーをクラスのメソッドに手動で渡しているため、静的メソッドを作成してこのように呼び出すのは少しばかげているようです。

Foo foo1 = new Foo();
foo1.bar1 = x;
foo1.bar2 = y;
sumbar1andbar2(foo1.bar1, foo1.bar2); 

しかし、以下のインスタンス メソッドはかなりきれいに見えますが、bar1 と bar2 の両方が null ではないことを保証するためのクリーンで簡単な方法を知りません。これにより、例外が発生します。

Foo foo1 = new Foo();
foo1.bar1 = x;
foo1.bar2 = y;
sumbar1andbar2();

ただし、メソッドがクラスの別のプロパティ (bar3 など) を変更する場合は、インスタンス メソッドの方が優れているように見えます。

4

3 に答える 3

2

メソッドの動作がFooタイプに固有である場合(そして他の場所では意味のある適用ができない場合)、またはFooの状態を変更する場合は、おそらくFooのインスタンスメソッドにする必要があります。

他の場所で使用したい一般的な計算(例のように)の場合、いくつかのオプションがあります。

ユーティリティクラスの静的メソッドにします。例:

public static class MyUtility {
    public static Int32 Add(Int32 x, Int32 y) { return x + y; }
}

Fooの拡張メソッド、その親クラス、またはxとyを定義するインターフェイスにします。

// Use as follows:
// var f = new Foo() { x = 5, y = 5 };
// var ten = f.MyUtility();
public static class MyUtility {
    public static Int32 Add(this Foo foo) { return Foo.x + Foo.y; }
}
于 2012-01-11T23:48:42.273 に答える
2

特定のインスタンスに関連する場合は、インスタンス メンバー (メソッド、プロパティ、またはフィールド) である必要があります。これらは最も一般的なケースであるため、例は豊富です。

特定のインスタンスに関連しない場合、インスタンス メンバーには、他の方法で使用しないインスタンスが必要です。良い例はMath.Maxです。 を呼び出しMath.Max(43, 23)た場合、結果は 43 が 23 より大きいという事実に関連しMath、アプリケーションの実行中に変更される可能性があるオブジェクトのプロパティには関連しません。

一部のクラスは静的メンバーのみを必要とするため、クラス自体を静的にし、インスタンス化することはまったくできません。

特定のインスタンスではなくクラスの性質に関連するプロパティも、同じ理由で静的にする必要があります。たとえばint.MaxValue、 は のプロパティでありint、eg 93 のプロパティではありません。

int.MaxValueの結果自体がであることに注意してくださいint。これは珍しいことではありません。その他の例としては、TimeSpan.Zeroおよびがありstring.Emptyます。これは便利であり、多くの参照型の重複を防ぐ上でパフォーマンス上の利点となる場合もあります (値型の場合は無関係であり、参照型の場合は誇張されていません)。これをやりすぎないことが重要です。4294967296 個の異なる静的プロパティをオンintにして、それらを「簡単に」呼び出す必要はありません! 通常、これは次の場合に役立ちます。

特殊なケースは、コンストラクターによって構築できません。

また:

特殊なケースは、一般的に使用される ( TimeSpan.Zero) および/または覚えるのに不便です (またはint.MaxValueよりも明確で覚えやすい)。もちろん、それが両方である場合はなおさらです。21474836470x7FFFFFFF

拡張メソッドは、インスタンス メンバーであるかのように呼び出すことができる静的メソッドです。これらは非常に便利ですが、通常は、可能な場合はインスタンス メンバーを使用することをお勧めします。インスタンス メンバーが不可能な場合に役立ちます。理由は次のとおりです。

  1. クラスのソースにアクセスできません (別のパーティのクラスです)。
  2. クラスではなくインターフェースで定義したい。
  3. null で呼び出し可能にする必要があります (これは C# では慣用的ではありませんが、他の言語ではより一般的です)。
  4. ジェネリックの特定のケースに対してそれを定義したいとします。たとえば、MyDictionary<TKey, TValue>その実装を作成した場合、TValue が既知の数値型である場合にのみ機能するため、格納された値に数値を追加するメソッドをIDictionary<TKey, TValue>定義できません。plusそのようなメソッドを拡張メソッドとして定義できます。そのようなメソッドは、intint Plus<TKey>(this MyDictionary<TKey, int> dict, int addend)の場合にインスタンス メンバーのように表示されますが、他の型パラメーターTValueの使用を妨げません。MyDictionary

これらのすべてのケースでは、拡張メソッドを使用する以外に選択肢はありませんが、インスタンス メンバーがジョブを実行する場合は使用しないでください。特に他の一部の .NET 言語は拡張メンバーを静的としてしか認識しないため、より明確です。

于 2012-01-12T00:08:42.717 に答える
1

まず、プロパティが null でないことを確認するための便利で簡単な方法があります。これはencapsulationと呼ばれます。プロパティがコンストラクターで設定されていることを確認し、公開することを選択した場合は、そのセッターで検証を行います。このようにして、オブジェクトが構築された後、プロパティは非 null になり (そうでない場合、コンストラクターは例外をスローします)、プロパティ セッターはプロパティ値を一貫した状態のままにします (そうでない場合、セッターは例外をスローします)。

実際の質問に移りましょう: 一方または両方の値がの他のインスタンスから来ている可能Fooがある場合は、計算方法を静的にします。それ以外の場合は、インスタンス メソッドにします。

PS メソッドが値を返し、パラメーターを持たず、副作用を生成しない場合は、メソッドではなく計算プロパティにすることを検討してください。

于 2012-01-11T23:50:35.283 に答える