web-dev-qa-db-ja.com

型自体ではなく型制約のあるジェネリックメソッドを使用する理由

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

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

単一の型制約(SomeSpecificReferenceType)のみがあることを念頭に置いて、単純にではなく、そのように記述することの違いと利点は何ですか。

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

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

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

14
John Wu

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

はい、そうです。

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

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

ただし、コードの内部でT(おそらくシリアライザへの引数として?)とneedを使用して、制約クラスではなくTを具体的に使用することは可能です。ときどき、制約がnew制約とペアになっているインターフェイスであり、メソッドの根性が何らかの理由でTsを作成することがわかります。

そのため、必要な制約バージョンが表示されることはまれですが、場合によってはそうなります。そして、メソッドsedがそれを必要とすることは常に可能ですが、今では必要なく、開発者はそれを残して、重大な変更を導入していません。

13
Telastyn

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

当時の理由は次のとおりでした:
(コードは異なる場合があります。ジェネリックメソッドの型パラメーターに制約がある理由の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)に置き換えることができます。しかし、その選択が良いか悪いかは分かりません。

これは著者(おそらく私または他の誰か)の例にすぎないと思いますすべての可能性を注意深く検討していないコーディングと同時に、別の質問/問題に集中しすぎています。

1
rwong