6

メソッドのオーバーロードを使用して、さまざまなジェネリック型に応じてさまざまな結果を取得したいと考えています。それは動作しません。私のコードはそれを明確に示しています。

static class Helper
{

    public static bool Can(int i)
    {
        return true;
    }

    public static bool Can(Object o)
    {
        return false;
    }
}

class My<T>
{
    public static bool can = Helper.Can(default(T));
}

Console.WriteLine(Helper.Can(default(int)));//True,it is OK

Console.WriteLine(My<int>.can);//false?? why the overload doesn't work
Console.WriteLine(My<Object>.can);//false

My<int>Helper.Can(int i) ではなく Helper.Can(Object o) を呼び出すのはなぜですか?

4

3 に答える 3

4

そのようには機能しません。

オーバーロードはコンパイル時に完全に解決されます。ジェネリック型パラメーターは実行時に解決されます。
コンパイラはそれが であることを認識していないため、コードTint常に を呼び出しますCan(Object)

于 2012-12-09T14:11:32.940 に答える
3

通常、コンパイル時に Object に解決されますが、dynamicキーワードを使用して実行時まで待機するように指示できます。

class My<T>
{
   public static bool can = CanWithDynamic();

   private static bool CanWithDynamic() {
      dynamic runtimeT = default(T);
      return Helper.Can(runtimeT);
 }

したがって、これはあなたがしようとしていることに対して機能し、適切なオーバーロードが呼び出されます。ただし、実行時に解決されるものと同様に、それに関連するパフォーマンス コストがあります。おそらくそれほど多くはありませんが、このメソッドを頻繁に呼び出すと、影響がある可能性があります。

于 2012-12-09T14:27:06.480 に答える
1

少し冗長ですが、リフレクションを使用して目的を達成できます。

class My<T>
{
    static bool doStuff()
    {
        var rightMehod = typeof(Helper).GetMethods().Where(p =>
            {
                if (!p.Name.Equals("Can"))
                    return false;

                if (!p.ReturnType.Equals(typeof(bool)))
                    return false;

                if (p.GetParameters().Length != 1)
                    return false;

                var par = p.GetParameters().First();
                return par.ParameterType.Equals(typeof(T));
            }).FirstOrDefault();

        if (rightMehod == null)
        {
            return Helper.Can(default(T));
        }
        else
        {
            return (bool)rightMehod.Invoke(null, new object[] { default(T) });
        }
    }

    public static bool can = doStuff();
}

こちらです、

My<string>.can == false
My<int>.can == true
My<object>.can == false

もちろん、ちょっとした工夫 (およびジェネリック型の使用) を行えば、そのスニペットをさまざまな状況で幅広く再利用できます。

追加の注意事項: この例では、特定の例に対して直接型比較を使用しました。継承された型を扱う場合、これは適切に機能しないことに注意してください (もちろん、いくつかのあいまいさもあります :)。

于 2012-12-09T14:23:26.537 に答える