68

メソッドが静的になる可能性があるのにそうではない場合、ReSharper が不平を言うのはなぜですか?

静的メソッドのインスタンスが 1 つだけ (型で) 作成され、パフォーマンスが節約されるためですか?

4

8 に答える 8

109

このコメントは、2つの重要なことを指摘しているため、非常に役立ちます。

  1. 問題のメソッドが実際にタイプの一部である必要があるかどうかを自問します。インスタンスデータを使用しないため、少なくとも独自のタイプに移動できるかどうかを検討する必要があります。それはタイプの不可欠な部分ですか、それとも本当に汎用のユーティリティメソッドですか?

  2. メソッドを特定のタイプに保持することが理にかなっている場合は、コンパイラーが静的メソッドに対して異なるコードを発行するため、パフォーマンスが向上する可能性があります。

于 2009-04-26T05:54:34.890 に答える
25

同じ警告の FxCop ドキュメントから (強調を追加):

「インスタンス データにアクセスしたり、インスタンス メソッドを呼び出したりしないメンバーは、静的 (Visual Basic では共有) としてマークできます。メソッドを静的としてマークすると、コンパイラはこれらのメンバーに非仮想呼び出しサイトを発行します。非仮想呼び出しの発行サイトは、現在のオブジェクト ポインタが null でないことを保証する各呼び出しの実行時のチェックを防止します.これにより、パフォーマンスが重要なコードの測定可能なパフォーマンスが向上する可能性があります. 場合によっては、現在のオブジェクト インスタンスへのアクセスの失敗は、正確性の問題。

于 2009-04-26T05:26:12.070 に答える
6

ここでその主題に関する非常に良い議論 (SO) . 私は、静的にすることができれば静的にするという陣営にいます。これは、インスタンス データを使用しないインスタンス メソッドを使用する理由を考えたからだと思います。その場合、それは本当にインスタンスメソッドですか、それとも実際にはクラスメソッドですか?

于 2009-04-27T02:01:15.813 に答える
5

static として宣言されている場合、メソッドを使用するためにクラスのインスタンスを作成する必要はありません...これにより、ガベージコレクターがオブジェクトを再利用する際に、構築処理、ヒープスペース、および cpu サイクルに必要な cpu サイクルが節約されます。ヒープ...

また、あなたの質問は、それが書かれているように

" ... 静的メソッドの 1 つのインスタンスのみが (型で) 作成されます..."

インスタンス メソッドの場合、作成されるクラスのインスタンスごとにメソッドのコードが繰り返されることを意味します。そうではありません。任意の型に対して作成するインスタンスの数に関係なく、メソッドのコードがメモリに読み込まれるのは 1 回だけです。各インスタンスのヒープに保存されるオブジェクトは、型の「状態」のみを保存します (非静的フィールドといくつかのその他の追跡変数)。

于 2009-04-26T05:23:34.807 に答える
3

これは苦情ではなく、ただのアドバイスです。

于 2009-04-26T05:24:01.997 に答える
1

私にとって、この ReSharper アドバイスの最大の利点は (警告、提案、またはヒントとして設定できます)。できるだけ多くのメソッドを静的にすることをお勧めします。静的メソッドは、それがメンバーであるクラスに直接依存しないため、これは良いことです。これは、静的メンバーとして別のクラスに簡単に移動できることを意味します。

ReSharper の静的に関するもう 1 つの巧妙なトリックは、「メソッドを静的にする」リファクタリングを使用して、関連する一連のメソッドを静的にすることです。これにより、一部の依存関係がメソッド パラメーターに移動されます。後でこの一連のメソッドを確認すると、すべてのメソッドが特定の型の特定のオブジェクトにアクセスしていることがわかります。その後、「メソッドを非静的にする」リファクタリングを使用して、そのオブジェクトを新しいthisポインターとして指定できます。これにより、メソッドが他のクラスに移動します。

これから:

internal class ClassA
{
    public ClassB Property { get; set; }

    public int Method()
    {
        var classB = Property;
        return classB.Property1 + classB.Property2;
    }
}

internal class ClassB
{
    public int Property1 { get; set; }
    public int Property2 { get; set; }
}

これに:

    public static int Method(ClassB property)
    {
        var classB = property;
        return classB.Property1 + classB.Property2;
    }

これに:

internal class ClassA
{
    public ClassB Property { get; set; }
}

internal class ClassB
{
    public int Property1 { get; set; }
    public int Property2 { get; set; }

    public int Method()
    {
        return Property1 + Property2;
    }
}
于 2009-04-27T01:54:35.503 に答える
1

静的メソッドの関数のスタックに「this」をプッシュする必要はありません。安い理由は他にもあります。

于 2009-04-26T05:23:28.067 に答える
0

static は最初の使用時にインスタンス化され、メモリに残ります。もう使わないなら、それは問題かもしれません。静的はテストが困難です(モークなど...)。

于 2015-02-10T11:38:12.740 に答える