3

リフレクションを使用して変換するメソッドがありList<T>ます。DataTable各リストが異なるタイプのオブジェクトを保持できる複数のリストを渡すことにより、DataSet を作成するためにそのメソッドを活用したいと考えています。

以下は、コンパイル時エラーが発生するコードです。

" The type arguments for method 'ExportToExcel.CreateExcelFile.ListToDataTable<T>(System.Collections.Generic.List<T>)' cannot be inferred from the usage. Try specifying the type arguments explicitly. " - 行 " var dt = Util.ListToDataTable(item);"

public static class Util
    {
        public static DataSet GetDataSet(List<string> title, List<IList> data)
        {
            DataSet ds = new DataSet();
            int idx= 0;
            foreach (var item in data)
            {
                //here I get compile time error "The type arguments for method
                // 'ExportToExcel.CreateExcelFile.ListToDataTable<T>
                // (System.Collections.Generic.List<T>)' cannot be inferred from the usage.
                // Try specifying the type arguments explicitly. "
                var dt = Util.ListToDataTable(item);
                if (title.Count >= idx)
                {
                    dt.TableName = title[idx];
                }
                idx++;
                ds.Tables.Add(dt);
            }
            return ds;
        }

        public static System.Data.DataTable ListToDataTable<T>(List<T> list)
        {
            var dt = new System.Data.DataTable();
            foreach (PropertyInfo info in typeof(T).GetProperties())
            {
                dt.Columns.Add(new DataColumn(info.Name, info.PropertyType));
            }
            foreach (T t in list)
            {
                DataRow row = dt.NewRow();
                foreach (PropertyInfo info in typeof(T).GetProperties())
                {
                    row[info.Name] = info.GetValue(t, null);
                }
                dt.Rows.Add(row);
            }
            return dt;
        }

    }

そして、これは私の呼び出しtestMethodです

       [TestMethod]
        public void TestDataSetGeneration_WithMultipleLists()
        {
            IList list = new List<User>();
            list.Add(new User(){FirstName = "Mahesh", LastName = "Chaudhari", IsExternal = true, UpdatedOn = DateTime.Now});
            list.Add(new User(){FirstName = "Mahesh1",LastName = "Chaudhari1",IsExternal = true,UpdatedOn = DateTime.Now});
            list.Add(new User(){FirstName = "Mahesh2",LastName = "Chaudhari2",IsExternal = false,UpdatedOn = DateTime.Now});

            IList hcps = new List<HCPUser>() { new HCPUser(){FirstName = "HCP1",LastName = "HCP1"}};

            var lists = new List<IList>();
            lists.Add(list);
            lists.Add(hcps);

            var titles = new List<String> { "Users", "HCPs"};
            var result = Util.GetDataSet(titles ,lists );
            Assert.IsTrue(result != null);
        }

メソッド Util.ListToDataTable には、実行時にのみ取得する特定のタイプが必要だと思います。このようなシナリオでは、このメソッドをどのように呼び出すのでしょうか?

4

2 に答える 2

1

コードが必要以上に複雑になっているようです。ジェネリック型と等しくないジェネリック型で終わります。IEnumerable前の回答で尋ねられたように単に持つことの何が問題になっていますか? 以下のコードは、単体テストに合格します。

    public static DataSet GetDataSet(List<string> title, IEnumerable<IEnumerable> data)
    {
        DataSet ds = new DataSet();
        int idx = 0;
        foreach (var item in data)
        {
            //here I get compile time error "The type arguments for method
            // 'ExportToExcel.CreateExcelFile.ListToDataTable<T>
            // (System.Collections.Generic.List<T>)' cannot be inferred from the usage.
            // Try specifying the type arguments explicitly. "
            var dt = Util.ListToDataTable(item);
            if (title.Count >= idx)
            {
                dt.TableName = title[idx];
            }
            idx++;
            ds.Tables.Add(dt);
        }
        return ds;
    }

    public static System.Data.DataTable ListToDataTable(IEnumerable list)
    {
        var dt = new System.Data.DataTable();
        var itm = list.OfType<object>().FirstOrDefault();
        if (itm == null)
            return dt;
        var typeProperties = itm.GetType().GetProperties();

        foreach (PropertyInfo info in typeProperties)
        {
            dt.Columns.Add(new DataColumn(info.Name, info.PropertyType));
        }
        foreach (var t in list)
        {
            DataRow row = dt.NewRow();
            foreach (PropertyInfo info in typeProperties)
            {
                row[info.Name] = info.GetValue(t, null);
            }
            dt.Rows.Add(row);
        }
        return dt;
    }
于 2015-01-15T13:22:40.083 に答える