12

このジェネリッククラスを考えてみましょう。

public class Request<TOperation> 
    where TOperation : IOperation
{
    private TOperation _operation { get; set; }

    public string Method { get { return _operation.Method; } }

    public Request(TOperation operation)
    {
        _operation = operation;
    }
}

上記のジェネリック版は、以下の非ジェネリック版に比べてどのような本当のメリットがありますか?

public class Request
{
    private IOperation _operation { get; set; }

    public string Method { get { return _operation.Method; } }

    public Request(IOperation operation)
    {
        _operation = operation;
    }
}

IOperationインターフェイスは次のとおりです。

public interface IOperation
{
    string Method { get; }
}
4

4 に答える 4

16

汎用バージョンでは、メソッドはタイプのパラメーターを取ることができますRequest<FooOperation>。のインスタンスを渡すRequest<BarOperation>ことは無効になります。
したがって、汎用バージョンを使用すると、メソッドは正しい操作の要求を確実に受け取ることができます。

于 2013-02-12T15:00:08.963 に答える
12

他のすべての良い答えに加えて、を実装する値型であるを使用して構築する場合、汎用バージョンはボクシングのペナルティを受けないことを追加します。非ジェネリックバージョンは毎回ボックス化されます。Request<T>TIOperation

于 2013-02-12T15:25:54.273 に答える
4

上記の場合、どのようなメリットが得られるかを言うのは難しいです。コードベースでこれをどのように使用するかによって異なりますが、次の点を考慮してください。

public class Foo<T> 
    where T : IComparable
{
    private T _inner { get; set; }

    public Foo(T original)
    {
        _inner = original;
    }

    public bool IsGreaterThan<T>(T comp)
    {
        return _inner.CompareTo(comp) > 0;
    }
}

に対して

public class Foo             
{
    private IComparable  _inner { get; set; }

    public Foo(IComparable original)
    {
        _inner = original;
    }

    public bool IsGreaterThan(IComparable  comp)
    {
        return _inner.CompareTo(comp) > 0;
    }
}

その後、を持っていた場合Foo<int>、おそらくそれをと比較したくないでしょうがFoo<string>、非汎用バージョンを使用してそれをロックダウンする方法はありません。

于 2013-02-12T15:09:49.060 に答える
3

たとえば、

public class SubOperation : IOperation 
{
    // implementation ...
}

public class OtherSubOperation : IOperation 
{
    // implementation ...
}

リクエストがOtherSubOperationアイテムを保持できないようにすることはできますが、どちらも有効なIOperationsになります。

于 2013-02-12T15:02:32.117 に答える