次のような一般的な関数があります。
public static class ExcelImport
{
public static List<T> Test<T>(string filename, string worksheetname) where T : class
{
return new List<T>(ExcelImport.Parse<T>(filename, worksheetname));
}
...
}
テスト関数を実行するオブジェクトのタイプがわかっている場合は、そのように簡単に呼び出すことができます (たとえば)。
List<OEE.Data.Equipment> result = ExcelImport.Test<OEE.Data.Equipment>(fileName.Text, worksheetName.Text);
しかし実際には、Test は OEE.Data 名前空間の任意のクラスに適用でき、ユーザーは Test 関数を起動する直前にコンボボックスで適切なクラスを選択します。
スイッチを使用して、コンボボックスの値ごとに異なる呼び出しをリンクすることもできますが、これは、OEE.Data にクラスを追加するたびに、新しいケースが必要になることを意味します。では、どうすれば型を動的に与えることができますか? 以下のコードは機能しません。
List<Type.GetType("OEE.Data.Equipment")> result = ExcelImport.Test<Type.GetType("OEE.Data.Equipment")>(fileName.Text, worksheetName.Text);
前もって感謝します!
サイモン
編集: Dishold の応答の下のコメントへの回答として、Test メソッドへの呼び出しの背後にあるコードを次に示します。
public static List<T> Test<T>(string filename, string worksheetname) where T : class
{
return new List<T>(ExcelImport.Parse<T>(filename, worksheetname));
}
private static IEnumerable<K> Parse<K>(string filename, string worksheetname) where K : class
{
IEnumerable<K> list = new List<K>();
string connectionString = string.Format("provider=Microsoft.Jet.OLEDB.4.0; data source={0};Extended Properties=Excel 8.0;", filename);
string query = string.Format("SELECT * FROM [{0}]", worksheetname);
DataSet data = new DataSet();
using (OleDbConnection con = new OleDbConnection(connectionString))
{
con.Open();
OleDbDataAdapter adapter = new OleDbDataAdapter(query, con);
adapter.Fill(data);
list = PopulateData<K>(data);
}
return list;
}
private static List<T> PopulateData<T>(DataSet data) where T : class
{
List<T> dtos = new List<T>();
foreach (DataRow row in data.Tables[0].Rows)
{
T dto = Activator.CreateInstance<T>();
PopulateFieldsFromDataRows(row, dto);
dtos.Add(dto);
}
return dtos;
}
次のように System.RuntimeType のインスタンスを作成できないため、新しい問題はメソッド PopulateData にあります。
T dto = Activator.CreateInstance<T>();