2012-04-30 19 views
6

私は職場で小さなクラスライブラリを作成しています。しかし、ジェネリックでわからないことがあります: ジェネリック型パラメータを使用して、その型パラメータを特定の基本クラスまたはインターフェイスに制約する必要があるのはなぜですか。ここで.NET(基本クラスとインターフェイスの制約)で型パラメータの制約がある点

は、私が何を意味するかの例です:

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

そしてここでは、ジェネリック医薬品

public class MyClass 
{ 
    private SomeBaseClass data; 
} 

ずに実装だそうなら、私はadvatageが表示されていない(同じこれら二つの定義ですここでジェネリックを使用しています)?

もしそうでない場合は、ここでジェネリックスを使用するとどんなメリットがありますか?

答えて

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(); 
+0

です。しかしジェネリッククラスに関しては、実際の違いはありません.... OK、ありがとう! –

+0

@AviShilon:ほとんどの場合、いいえ。ジェネリック型制約と通常の静的型定義との唯一の違いは、ジェネリック型制約が 'class'と' struct'キーワードを指定して、それぞれ参照型または値型に制約することができることです。これは通常の静的型付け構文では表現できません。 'GetType()'(これは 'T'よりも派生しているかもしれませんし、値が' nullの場合はまったく動作しません)に依存せずに 'typeof(T)'のようなことを*行うこともできます')。 –

1

違いは、前者は特定の型として新しいクラスを定義することです。後者は単純にそのタイプのフィールドを持つプレーンクラスを定義します。

1

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

+0

グレートマレック。親切な助けをありがとう。 –

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(安全ではない)にキャストバックする必要があります。

+0

優れた例。他の人がこの答えを指定しているので、これは実際には2つの定義の主な違いだと思います。それから恩恵を受けるのは消費者です。ジェネリック/非ジェネリックの元のクラスはあまりありません。ありがとう! –

1

私は違いの膨大な量が第2のクラスのメンバーにだけ制約であるのに対し、ジェネリックバージョンは、あなたのクラスを制約されることを除いてないと思います。最初のクラスにさらにメンバーとメソッドを追加した場合、同じ制約が適用されます。