2016-10-21 9 views
3

私はこれに悩まされています。フィールドがジェネリックパラメータを使用しているかどうかを確認する

次のように私はクラスを持っている:

public class Foo<T> 
{ 
    public List<T> Data; 
} 

は今、私はこのクラスを反映して、フィールドのデータが使用されている一般的なパラメータを持っていることを決定する方法を考え出すしたいコードを書いています。

私の最初のアプローチは、できる限り多くのレベルを下げ続けていましたが、一度IsGenericParameterフィールドをtrueに設定すると、「Generic Argument」という文字列を代わりにタイプ名を反映させるのではなく、これを私が望むように動作させるように思える。

私は周りを見回しましたが、私が見つけたすべての解決策は、現時点でこれで終わりを指しているようです。

+1

System.Type'あなたが持っているインスタンス? 'typeof(Foo <>)'や 'typeof(Foo )'のようなものですか? – dasblinkenlight

+0

こんにちは@dasblinkenlightインスタンスはFoo です。 – alexc95

+0

ちょうどこれに追加するために、私はその後、Foo を使用して、データフィールドに、リストの後に、文字列自体がtrueに設定されている 'IsGenericParameter'を持っていないので、フィールドを繰り返します。 – alexc95

答えて

1

ここでは、クラス型パラメータに依存するジェネリック型と、そうでないジェネリック型を区別する方法を示します。ジェネリック型定義を取得し、その型の引数を引っ張って

class Foo<T> { 
    public List<T> field1; // You want this field 
    public List<int> field2; // not this field 
} 

スタート:この例を考えてみましょう

var g = typeof(Foo<string>).GetGenericTypeDefinition(); 
var a = g.GetGenericArguments(); 

これはあなたのジェネリック型パラメータTを表す単一のタイプの配列を与えます。今、あなたはすべてのフィールドを通過し、このように、フィールドタイプのジェネリック型引数の中で、そのタイプを検索することができます。

foreach (var f in g.GetFields()) { 
    var ft = f.FieldType; 
    if (!ft.IsGenericType) continue; 
    var da = ft.GetGenericArguments(); 
    if (da.Any(xt => a.Contains(xt))) { 
     Console.WriteLine("Field {0} uses generic type parameter", f.Name); 
    } else { 
     Console.WriteLine("Field {0} does not use generic type parameter", f.Name); 
    } 
} 

このコードproduces the following output: `初期は何

Field field1 uses generic type parameter 
Field field2 does not use generic type parameter 
+1

ありがとうございます。これは私が正しい場所に得るのを助けた:) – alexc95

3

あなたはIsGenericType、ないIsGenericParameterをしたい:

bool isGeneric = typeof(Foo<int>).GetField("Data").FieldType.IsGenericType; 

あなたがListのパラメータを知りたいなら、あなたは1つの以上のレベルを見下すする必要があり、汎用的である:

bool isGeneric = typeof(Foo<>).GetField("Data") 
           .FieldType 
           .GetGenericArguments()[0] // only generic argument to List<T> 
           .IsGenericParameter; 

DataフィールドがDictionaryの場合はDictionary<string, T>となります。どのタイプが汎用パラメータを使用していたかはどのように判断するのですか?

タイプの

コールGetGenericArguments、それが一般的なものであればかであるかどうかを確認するためにタイプの汎用パラメータを見ると基本的には、IsGenericParameterが使用されている結果の配列

public class Foo<T> 
{ 
    public Dictionary<string, T> Bar; 
} 

Type[] types = typeof(Foo<>).GetField("Bar").FieldType.GetGenericArguments(); 

Console.WriteLine("{0}\n{1}", 
    types[0].IsGenericParameter, // false, type is string 
    types[1].IsGenericParameter // true, type is T 
); 

に各タイプを見てタイプがsepcifiedです。

+1

これは論理的ですが、Dataフィールドが辞書付き辞書である場合はどうでしょうか。 ...どのタイプが汎用パラメータを使用していたのか? – alexc95

+0

ありがとうございます - これも正しい場所に手伝ってくれましたが、上記のユーザーはほんの少し速かったので、それを正解とマークするのは公正だと思いました:) – alexc95

関連する問題