6

私は仕事で小さなクラスライブラリに取り組んでいます、そしてそれは当然このタスクのためにジェネリックを使用することを含みます。しかし、ジェネリックスではよくわからないことがあります。ジェネリック型パラメーターを使用してから、型パラメーターを特定の基本クラスまたはインターフェースに制約する必要があるのはなぜですか。

これが私の言いたいことの例です:

public class MyGenericClass<T> where T : SomeBaseClass
{
    private T data;
}

そして、これがジェネリックなしの実装です

public class MyClass
{
    private SomeBaseClass data;
}

これらの2つの定義は同じですか(はいの場合、ここでジェネリックを使用する利点はわかりません)?

そうでない場合、ここでジェネリックを使用することで何が得られますか?

4

5 に答える 5

7

ジェネリック医薬品のほとんどすべての使用法と同様に、利益は消費者にもたらされます。型を制約すると、パラメーターを強く型付けすることで得られるのと同じ利点が得られます(または、パブリックパラメーターのないコンストラクターがあることを確認したり、値または参照型であることを確認したりできます)。クラスまたは関数のコンシューマー。

たとえば、ジェネリックスを使用すると、特定の値である場合に、指定された実際の型を取得できます。

この例は少し工夫されていますが、これを見てください:

public class BaseClass
{
    public void FunctionYouNeed();
}

public class Derived : BaseClass
{
    public void OtherFunction();
}

public class MyGenericClass<T> where T: BaseClass
{
    public MyGenericClass(T wrappedValue)
    {
        WrappedValue = wrappedValue;
    }

    public T WrappedValue { get; set; }

    public void Foo()
    {
        WrappedValue.FunctionYouNeed();
    }
}

...

var MyGenericClass bar = new MyGenericClass<Derived>(new Derived());

bar.Foo();

bar.WrappedValue.OtherFunction();
于 2012-04-30T13:25:11.530 に答える
1

違いは、前者は新しいクラスを特定の型として定義することです。後者は、その型のフィールドを持つ単純なクラスを定義するだけです。

于 2012-04-30T13:28:11.367 に答える
1

主な違いは使い方です。最初のケースでは、使用法には次のものがあります。

MyGenericClass<SomeDerivedClass> Variable
Variable.data.SomeDerivedProperty = X

そのため、そのクラスを使用すると、キャストバックせずに SomeDerivedClass から何かにアクセスできます。

2 番目の例では、これは許可されません。

MyClass.data = SomeDerivedClassInstance
MyClass.data.SomeDerivedProperty = X //Compile Error
((SomeDerivedClass)MyClass.data).SomeDerivedProperty = X //Ewwwww

派生クラスに固有のものを使用するには、SomeDerivedClass (安全でない) にキャストし直す必要があります。

于 2012-04-30T13:29:45.940 に答える
1

ジェネリック バージョンがClassを制約しているのに対し、2 つ目はクラスのメンバーに対する単なる制約であることを除いて、大きな違いはないと思います。最初のクラスにさらにメンバーとメソッドを追加すると、同じ制約が適用されます。

于 2012-04-30T13:29:56.990 に答える
1

それはすべてタイプセーフに関するものです。ジェネリックを使用すると、ジェネリック クラスで必要な API を定義する基本型の代わりに具象型 (T) を返すことができます。したがって、メソッドの呼び出し元は、結果を具象型にキャストする必要はありません (これはエラーが発生しやすい操作です)。

于 2012-04-30T13:28:52.167 に答える