3

.Net でメソッドをオーバーロードすることに関連するコストはありますか?

したがって、次のような3つの方法がある場合:

Calculate (int)
Calculate (float)
Calculate (double)

これらのメソッドは、実行時に Calculate メソッドに渡された内容に基づいて「動的に」呼び出されます。このオーバーロード解決のコストはいくらになるでしょうか?

別の方法として、単一の Calculate を使用してメソッド本体で違いを生むこともできますが、メソッドが呼び出されるたびに型を評価する必要があると思いました。

おそらくオーバーヘッドなしでこれを解決するためのより良い方法/設計はありますか? またはさらに良いことに、このようなケースを処理するためのベストプラクティスは何ですか? 同じクラス/メソッド名を持ちたいのですが、動作は異なります。

編集:ありがとうございました。違いがある場合は、1つだけ。これらのメソッド用の DLL と、ユーザーがこれらのメソッドを (型を指定せずに) UI 項目として追加できるようにする C# で記述されたプログラムがあると思っていました。ユーザーが UI 項目 Calculate (5)、Calculate (12.5) などを追加し、C# アプリがこれを実行すると、オーバーヘッドは発生しませんか?

4

7 に答える 7

9

この質問は、ポリモーフィズムではなく、メソッドのオーバーロードに関するものです。私の知る限り、メソッドのオーバーロードによるペナルティはありません。コンパイラは、渡される引数の型に基づいて、コンパイル時に呼び出すメソッドを判断するからです。

ポリモーフィズムは、基本クラスの代わりに派生型を使用している場合にのみ機能します。

于 2009-02-26T22:33:33.670 に答える
4

メソッドのオーバーロード (つまり、メソッド テーブル スロット) は実行時に動的に解決されるのではなく、コンパイル時に静的に解決されるため、メソッドをオーバーロードしてもコストはかかりません。

virtual実際の実装が派生型によってオーバーライドされ、具体的な型に基づいて実際のメソッドが選択されるメソッドについて考えていると思います。ただし、仮想メソッドは同じメソッド テーブル スロットを占有するため、オーバーロードとは関係ありません。

于 2009-02-26T22:33:54.777 に答える
2

コンパイラはコンパイル時に呼び出すメソッドを決定するため、実行時の「コスト」はありません。生成される IL は、適切なパラメーターを受け取るメソッドを明確に呼び出します。

たとえばこれ」

public class Calculator
{
    public void Calculate(int value)
    {
        //Do Something
    }
    public void Calculate(decimal value)
    {
        //Do Something
    }
    public void Calculate(double value)
    {
        //Do Something
    }
}

static void Main(string[] args)
{
    int i = 0;
    Calculator calculator = new Calculator();
    calculator.Calculate(i);
}

次の呼び出しは、変数 "i" を計算するために IL で行われます。

L_000b: callvirt instance void ConsoleApplication1.Calculator::Calculate(int32)

メソッドの型が int32 であることを指定していることに注意してください。これは、Main メソッドから渡された変数と同じ型です。

したがって、コストがかかる場合は、コンパイル時のみです。心配ない。

JaredParが以下に記したように:

あなたの質問には誤解があります。C# のオーバーロードされたメソッドは、実行時に動的に呼び出されません。すべてのメソッド呼び出しは、コンパイル時に静的にバインドされます。したがって、実行時にメソッドを「検索」する必要はありません。どのオーバーロードが呼び出されるかは、コンパイル時に事前に決定されます。

于 2009-02-26T22:44:14.457 に答える
1

IL では、タイプに基づいて 3 つの異なるメソッドが生成されます。唯一のコストは、あるタイプから別のタイプにキャストする場合ですが、大量に行う必要がない限り、そのコストは重要ではありません. したがって、Calculate(double) に固執して、そこからキャストできます。

于 2009-02-26T22:30:03.617 に答える
1

あなたの質問には誤解があります。C# のオーバーロードされたメソッドは、実行時に動的に呼び出されません。すべてのメソッド呼び出しは、コンパイル時に静的にバインドされます。したがって、実行時にメソッドを「検索」する必要はありません。どのオーバーロードが呼び出されるかは、コンパイル時に事前に決定されます。

注: これは、C# 4.0 と動的では少し異なります。動的オブジェクトでは、オブジェクトの型に基づいて実行時にオーバーロードが選択される可能性があります。ただし、これは C# 3.0 以下には当てはまりません。

于 2009-02-27T04:46:22.463 に答える