型自体の代わりに、型制約のあるジェネリックメソッドを使用するのはなぜですか?


14

別のStackExchangeの質問で、このプロトタイプを使用している人に気付きました。

void DoSomething<T>(T arg) where T: SomeSpecificReferenceType
{
    //Code....
}

型の制約は1つだけであることに注意してください(SomeSpecificReferenceType)。単純にではなく、そのように記述することの違いと利点は何ですか?

void DoSomething(SomeSpecificReferenceType arg)
{
    //Code....
}

どちらの場合も、argコンパイル時の型チェックの対象となります。どちらの場合も、メソッドの本体は、argコンパイル時に認識されている特定の型の(またはその子孫である)知識に安全に依存できます。

これは、熱心な開発者が通常の継承について学ぶ前にジェネリックについて学ぶ場合ですか?または、メソッドシグネチャがこのように記述される正当な理由がありますか?


私はかろうじてC#を知っているので、これは単なる推測に過ぎませんが、これにより、動的ディスパッチではなく、より効率的な静的ディスパッチが可能になりませんか?
アントンバルコフスキー

回答:


13

これは、熱心な開発者が通常の継承について学ぶ前にジェネリックについて学ぶ場合ですか?

はい、おそらくそうです。

または、メソッドシグネチャがこのように記述される正当な理由がありますか?

たぶん。一般に、を含む戻り値T、またはを使用する別のパラメーターがあれば、より意味がありますT

しかし、コードの内部がT(おそらくシリアライザーの引数として?)を使用し、制約クラスではなく具体的に使用する必要がある可能性がTあります。制約がnew制約とペアになっているインターフェイスであり、メソッドのガットがT何らかの理由でsを作成する場合があります。

そのため、必要な制約バージョンを確認することはまれですが、必要な場合もあります。そして、それは方法があることは常に可能です使用し、それを必要とするが、今せず、互換性に影響する変更を導入しないことですと、開発者はそれを残しました。


1

これを含む回答を入力したことを覚えていると思います。

当時の理由は次のとおりでした:(
コードは異なる場合があります。ジェネリックメソッドの型パラメーターに制約がある理由の1つを示すためだけです。)

class SomeSingleton
{
    static Dictionary<Type, List<object>> staticTypeSpecificList;
    public void AddObjectToList<T>(T t) where T : SomeCommonThing
    {
        Type tt = t.GetType();
        List<object> list;
        if (!staticTypeSpecificList.TryGet(tt, out list))
        {
            list = new List<object>();
            staticTypeSpecificList.Add(tt, list);
        }
        list.Add(t);
    }
}

基本的に、コードは、型操作自体を手動でコーディングします。また、いくつかの反射のものと混同される可能性があります。

例えば、使用することによってMethod<T>(T arg) where T : ...、一つは置き換えることができarg.GetType()typeof(T)。ただし、その選択が良いか悪いかはわかりません。

これは著者(おそらく私または他の誰か)がコーディングのすべての可能性慎重に考えていないと同時に、別の質問/問題に集中しすぎている例だと思います。


「arg.GetType()をtypeof(T)に置き換えることができます」。これは、たとえばシリアル化の場合にargが有効にnullになる場合に便利です。
ウォルペン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.