4

この質問に触発されて、Mono 2.10.9 と Visual Studio 2010 で次のコードを試しました。

public class Example
{
    public static void Main()
    {
        Foo(1);
    }

    public static void Foo( dynamic x )
    {
        Example.Bar(x);
    }

    static void Bar( dynamic x )
    {
        x++;
    }

    int count;
    void Bar( int x )
    {
        count++;
    }
}

ご覧のとおり、Fooは静的であるため、静的にしかアクセスできませBarん。静的バージョンを明示的に呼び出します。

static void Bar( int x )非静的バージョンが存在するため、を宣言できないことはわかっています。

ただし、非静的の引数の型をBar、たとえば文字列に変更すると、すべてがうまくいきます。

何故ですか?ここでのルールは何ですか?静的メソッドを呼び出すことは可能ですか?

多分それはMono DLRの問題ですか?

編集:明確にするために。静的メソッドへの明示的な呼び出し(少なくとも明示的だと思います) を静的メソッドへの呼び出しに変えるルールを知りたいですか? これは、静的コンテキストからは明らかに不可能です。

または、そのようなルールがない場合、それはバグでしょうか? この動作は何とか回避できますか?

4

2 に答える 2

1

そこにある重要なステートメントは、「非静的バージョンが存在するため、静的な void Bar( int x ) を宣言できないことを知っています。」 です。dynamic キーワードを使用すると、オーバーロードの解決が実行時に延期されますが、実行時にそのルールが免除されるわけではありません。

オーバーロードの解決が最終的に行われると、DLR は使用可能なすべてのオプションを評価し、最適なオプションを選択します。この解決時間まで、動的型のパラメーターは型オブジェクトのように動作します (こちらを参照)。)。したがって、通常、int を取るより具体的なメソッドがオーバーロード解決の勝者となり、動的/オブジェクトを取るメソッドよりも選択されます。これは、通常はインスタンス メソッドが勝つことを意味します。DLR は、同じシグネチャを持つ 2 つのメソッドが静的であっても変化しないことを認識しています。利用可能なオプションを評価するとき、あなたが期待していることは、「あはは!この場合、static void Bar(dynamic x) は static void Bar(int x) として解釈できます」と言うことです。ただし、それがそうであった場合、それ以外の場合は同一の静的メソッドと非静的メソッドを持たないという規則に違反します。オプションの内部リストには、静的および非静的 Bar メソッドが含まれ、どちらも同じシグネチャを持ちます。だから、それは言えません。これにより、たまたまインスタンスメソッドである唯一の他のオプションが残ります。この状況ではこれは役に立たないため、DLR は RuntimeBinderException をスローします。インスタンス Bar のパラメーターを int 以外に変更すると、メソッド シグネチャが衝突しないため、DLR は静的動的 Ba​​r を int として解釈し、代わりにそのオーバーロードを選択できます。

于 2013-01-13T01:25:36.877 に答える
0
    static void Bar( dynamic x )
    {
        x++;
    }

    int count;
    void Bar( int x )
    {
        count++;
    }

静的関数は次のように見ることができます (したがって、int 型パラメーターを使用した静的メソッドへの呼び出しは、非静的でより適切なメソッドを呼び出します)。

    static void Bar( dynamic x )
    {
        if (x is Int)
           Bar(x); //Count++

        else
           x++;
    }
于 2012-10-11T15:49:41.917 に答える