2017-11-21 6 views
0

私のC#アプリケーションでは、タプルのインスタンスを作成する必要があります。しかしここにキャッチがあります - タプルのタイプは、実行時にのみ事前にわかりません。 Tupleに存在する可能性のある任意の型のインスタンスを作成できるメソッドがある場合、そのようなTupleインスタンスを作成するためにリフレクションを使用する方法はありますか?たとえば、私はこれらの線に沿って考えていますが、私はそれを働かせることができません:C#リフレクトでタプルのデフォルトオブジェクトを作成する

if (type typeof(Tuple)) 
{ 
    FieldInfo[] fieldInfoArray = type.GetFields(); 
    object[] = CreateArrayOfObjectsFromFieldInfoArray(fieldInfoArray); 
    return new Tuple(objectArray); 
} 

これを行うより良い方法はありますか?

+2

はyou'reが探して何を、この次のとおりです。https ://stackoverflow.com/questions/266115/pass-an-instantiated-system-type-as-a-type-parameter-for-a-generic-class – HimBromBeere

+0

タプルについて Steve

+0

私はできると思いますまた、Tuple.Create( "cat"、2、true)のようにTuple.Createを使用します。 –

答えて

0

Tuple.Createメソッドを使用すると、コードを静的に書くときとリフレクションを使うときの両方で、コンストラクタを使うよりもはるかに簡単にオブジェクトを構築できます。 FieldInfoオブジェクトを使用して、Createのどのオーバーロードを呼び出すか把握し、そのオーバーロードを呼び出すときの値を渡すことができます。

FieldInfo[] fieldInfoArray = type.GetFields(); 
object[] values = CreateArrayOfObjectsFromFieldInfoArray(fieldInfoArray); 
Type[] typeArguments = fieldInfoArray.Select(fieldInfo => fieldInfo.FieldType).ToArray(); 
return typeof(Tuple).GetMethods() 
    .FirstOrDefault(method => method.Name == "Create" && method.GetParameters().Length == typeArguments.Length) 
    ?.MakeGenericMethod(typeArguments) 
    ?.Invoke(null, values); 
+0

これはうまくいくように見えますが、タイプがタプルかどうかをテストする必要があります。私は次のように動作すると思ったが、そうではない:typeof(Tuple).IsAssignableFrom(type);タプルタイプをテストする正しい方法は何でしょうか? – user304582

+0

@ user304582タイプがすでに*タプルの場合は、新しいタプルを作成する必要はありません。すでにタプルがあります。それにかかわらず、それはあなたが尋ねたものとはまったく異なる質問です。 – Servy

+0

すばらしい、ありがとう - 私はタプルのテストでいくつかのグーグルを行い、必要に応じて別の質問を投稿します。その間、私はあなたの答えを受け入れたものとしてマークします。 – user304582

0

私は仕事に最初の回答でコードを取得できませんでしたが、いくつかの試行錯誤の後、私は仕事に次しまっ:

Type[] typeArray = type.GetGenericArguments(); 
object[] values = CreateArrayOfObjectsFromFieldInfoArray(typeArray); 
defaultObject = type.GetConstructor(typeArray)?.Invoke(values); 
関連する問題