2013-03-22 25 views
13

はのは、次のように私は、一般的なクラスがあるとしましょう:いくつかの他のクラスでワイルドカードと同等

public class GeneralPropertyMap<T> 
{ 
} 

私はGeneralPropertyMap<T>の配列で取る方法があります。 Javaでは、GeneralPropertyMapのいずれかのタイプを含む配列方法を取るために、次のようになります。

private void TakeGeneralPropertyMap(GeneralPropertyMap<?>[] maps) 
{ 
} 

後、私たちはのための任意のタイプでGeneralPropertyMapの束を渡しTakeGeneralPropertyMapを呼び出すことができるように私たちは、ワイルドカードを使用しますTそれぞれは、次のように:

GeneralPropertyMap<?>[] maps = new GeneralPropertyMap<?>[3]; 
maps[0] = new GeneralPropertyMap<String>(); 
maps[1] = new GeneralPropertyMap<Integer>(); 
maps[2] = new GeneralPropertyMap<Double>(); 
//And finally pass the array in. 
TakeGeneralPropertyMap(maps); 

ノー成功とC#で同等のを把握しようとしています。何か案は?

+0

あなたは関数が取る作るしようとしている 'GeneralPropertyMap [] maps' ..私はそれが理由共分散 – Ankur

答えて

3

C#で、これには直接相当するものはありません。 C#ので

、これは多くの場合、あなたの一般的なクラスが非ジェネリックインターフェイスまたは基本クラスを実装することによって行われることになります。

interface IPropertyMap 
{ 
    // Shared properties 
} 

public class GeneralPropertyMap<T> : IPropertyMap 
{ 
} 

あなたは、これらの配列を渡すことができます。

IPropertyMap[] maps = new IPropertyMap[3]; 
// ... 

TakePropertyMap(maps); 
+0

@EricJで動作するはずですね。問題を読み違えていた...私は一般的な方法を理解し、彼らはこのケースではないだろう –

+0

を修正しました。私がそれを呼び出すたびに、私はGeneralPropertyMapに1つのタイプしか指定できません。だから、私はそれをGeneralPropertyMap []の配列、またはGeneralPropertyMap の配列のいずれかに渡して呼び出すことしかできません。 – AxiomaticNexus

15

C#のジェネリックスは、Javaのジェネリックよりも強力な保証をします。したがって、あなたがC#でやりたい、あなたはそのクラス(またはインタフェース)の非ジェネリックバージョンからGeneralPropertyMap<T>クラスの継承を聞かせする必要があります。

public class GeneralPropertyMap<T> : GeneralPropertyMap 
{ 
} 

public class GeneralPropertyMap 
{ 
    // Only you can implement it: 
    internal GeneralPropertyMap() { } 
} 

今、あなたは行うことができます。

private void TakeGeneralPropertyMap(GeneralPropertyMap[] maps) 
{ 
} 

そして:

GeneralPropertyMap[] maps = new GeneralPropertyMap[3]; 
maps[0] = new GeneralPropertyMap<String>(); 
maps[1] = new GeneralPropertyMap<Integer>(); 
maps[2] = new GeneralPropertyMap<Double>(); 
TakeGeneralPropertyMap(maps); 
+1

インターフェイスでは、 "TakeGeneralPropertyMap"メソッドからワイルドカードを使用する方法を取っている可能性が高いので、まだ十分ではありません。ジェネリックタイプのしかし、この答えは少なくとも近づいています。ありがとう:-) – AxiomaticNexus

0

GeneralPropertyMapIGeneralPropertyMap)のメンバーからインターフェースを作成し、その後、引数としてIGeneralPropertyMap[]を取るが。他の人が指摘しているよう

8

ている間は、そのユースケースの一部がcovariance/contravarianceで覆うことができる、C#でのワイルドカードへの正確な対応はありません。

public interface IGeneralPropertyMap<out T> {} // a class can't be covariant, so 
             // we need to introduce an interface... 

public class GeneralPropertyMap<T> : IGeneralPropertyMap<T> {} // .. and have our class 
                  // inherit from it 

//now our method becomes something like 
private void TakeGeneralPropertyMap<T>(IList<IGeneralPropertyMap<T>> maps){} 

// and you can do 
    var maps = new List<IGeneralPropertyMap<Object>> { 
     new GeneralPropertyMap<String>(), 
     new GeneralPropertyMap<Regex>() 
    }; 
    //And finally pass the array in. 
    TakeGeneralPropertyMap<Object>(maps); 

の注意点は、あなたが値型と共分散を使用することができないということですので、私たちのリストに新しいGeneralPropertyMap<int>()を追加すると、コンパイル時に失敗しました。

cannot convert from 'GeneralPropertyMap<int>' to 'IGeneralPropertyMap<object>' 

このアプローチは、あなたがGeneralPropertyMapに含めることができる種類を制限したい場合には、あなたのクラス/インタフェースの非ジェネリックバージョンを持つよりも便利かもしれません。その場合:

public interface IMyType {} 
public class A : IMyType {} 
public class B : IMyType {} 
public class C : IMyType {} 

public interface IGeneralPropertyMap<out T> where T : IMyType {} 

はあなたが持つことができます:

var maps = new List<IGeneralPropertyMap<IMyType>> { 
    new GeneralPropertyMap<A>(), 
    new GeneralPropertyMap<B>() , 
    new GeneralPropertyMap<C>() 
}; 
TakeGeneralPropertyMap(maps);