2017-02-02 16 views
7

私はプログラミングコースで見つけたものでかなり混乱しています。簡単に言うと一般的なメソッドパラメータへのインターフェイスの実装VSメソッドの引数へのインターフェイスの実装

- 私は建設することを持っている方法が見つかりました: - :

public void MethodB(IComparable a) 
    { 
     //... 
    } 

です私たちは、これを使用してachiveことができ、同じ正確な効果を

public void MethodA<T>(T a) where T : IComparable 
    { 
     //... 
    } 

そして、私の知る限りをそれらの2つの方法はどういうわけか互いに異なり、それらのうちの1つは他のものより利点がありますか?そうであれば、そのうちの1つが使い易いシナリオをどうやって見ることができますか?

ありがとうございます!

+1

最初のケースでは、メソッドはパラメータとしてより具体的な型を持ちますが、その型はICmparableを継承しますが、後者の場合はIComparable型のオブジェクトを渡す必要があります –

+1

わかりませんが、あなたが 'IComparable'を実装する' struct'を持っているかどうかを推測します。最初のメソッドを呼び出すと 'struct'は呼び出されません。 –

+0

あなたはいつでも 'public void MethodA (IComparable t)'に行くことができます。 –

答えて

5

私は興味があったので、私は少しtestcodeを自分で作っ:

public interface ITest 
{ 
    int Value { get; set; } 
} 
public struct TestStruct : ITest 
{ 
    public int Value { get; set; } 
} 

private static void TestMethodGeneric<T>(T value) where T : ITest 
{ 
} 
private static void TestMethodNonGeneric(ITest value) 
{ 
} 

そして、私は両方のコールを使用して私の主な方法で:

TestStruct ts = new TestStruct {Value = 10}; 
TestMethodNonGeneric(ts); 
TestMethodGeneric(ts); 

そして、これが結果としてILコードです:

非汎用:

IL_0031: ldloc.0  // ts 
IL_0032: box   Tests.Program/*02000002*//TestStruct/*02000026*/ 
IL_0037: call   void Tests.Program/*02000002*/::TestMethodNonGeneric(class Tests.Program/*02000002*//ITest/*02000025*/)/*06000002*/ 
IL_003c: nop   

汎用:

IL_0059: ldloc.0  // ts 
IL_005a: call   void Tests.Program/*02000002*/::TestMethodGeneric<valuetype Tests.Program/*02000002*//TestStruct/*02000026*/>(!!0/*valuetype Tests.Program*//*02000002*//*/TestStruct*//*02000026*//**/)/*06000001*/ 
IL_005f: nop 

だから、あなたが見る、ジェネリックバージョンでは、特定のタイプを使用し、そのための何のボクシングは発生しません。
非汎用バージョンでは、structの値をITestにキャストしなければならないので、ボックス化されます。したがって、ジェネリック版は(非常に小さい)パフォーマンス上の利点を持っています。

ちょうど私の2セント、2つのアプローチで多かれ少なかれ重要な違いがあるかもしれません。

+0

驚くべき答え!ありがとう! –

+0

ボクシングが本当の問題でない限り、私は個人的にこのシナリオの厳密なタイピング(非ジェネリック)バージョンを好むだろう。ジェネリックバージョンはちょっと奇妙に見えます。しかし、私は弾丸に耐える技術的な議論を見つけることはできません。 –

関連する問題