C# 在不知道特定类型的情况下访问泛型方法

标签 c# generics generic-method

我有一个方法可以转换 List<T>DataTable使用反射。我想通过传递多个列表来利用该方法创建数据集,其中每个列表可能包含不同类型的对象。

下面是给我编译时错误的代码:

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]
        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 方法需要仅在运行时获取的特定类型。在这种情况下,我将如何调用此方法?

最佳答案

您可以构造一个通用的 MethodInfo对象使用 MethodInfo.MakeGenericMethod并通过反射调用它,但我认为没有理由 ListToDataTable方法需要通用。

一种选择是更改 List<T>到一些非通用的东西,比如 IEnumerable .不过,您必须通过从列表中获取第一个元素来找出类型。

另一个选择是 LINQ:

public static System.Data.DataTable ListToDataTable<T>( object[] list )
{
    ....
}

var dt = ListToDataTable( item.Cast<object>().ToArray() );

如果列表为空,这两个选项都无法找出类型。也许其他人有更简洁的方法。

编辑:我现在看到您的数据是非通用的 IList无论如何从一开始,所以类型基本上已经丢失了。

关于C# 在不知道特定类型的情况下访问泛型方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27963402/

相关文章:

c# - 假货比 Mocks 好吗?

c# - Shell 脚本与高级解释语言(C#/Java/等)的性能比较

c# - 将 ASP.NET Identity 用户链接到用户详细信息表

generics - 在 .NET Core 中使用字段名动态构建 IQueryable Select 子句

java - 如何使用泛型方法将 List<T> 转换为 Array t[](对于基本类型)?

c# - 使用 JSON.net 反序列化 JSON 流

c# - 通用委托(delegate)重复定义 - 为什么?

delphi - 为什么 TFunc<T> 可以正确遵循,但 TFunc<T> 的数组 [0..1] 却不能?

java - 在java中使用 'diamond'表示法表示方法

java - 使用 Mockito 进行泛型方法的 ClassCastException