将通用类型传递给扩展方法

3

我正在尝试创建一个通用的方法来执行查询,可以传递存储过程的名称和参数(如果有)。

执行查询后,结果将存储在 DataTable 中,需要将其转换为 List。

DataTableToList()

是一个扩展方法,可以完成相同的操作。

只显示相关代码

调用者

        var results=  dh.ExecuteDataSet<EmployeeModel>("USP_GetEmployeeByID", new Dictionary<string, IConvertible>()
        {
                 {"@ID", 1000}
             });

DAL代码

public IEnumerable<T>  ExecuteDataSet<T>(string storedProcName, IDictionary<string, IConvertible> parameters = null)
            {                            
                    var result = db.ExecuteDataSet(q);

                    DataTable dtResult = result.Tables[0];

                    var t = dtResult.DataTableToList<T>();  //Compile time error: The type T must be a reference type in order to use it as parameter 

                        return t;

                }

扩展方法

public static List<T> DataTableToList<T>(this DataTable table) where T : class, new()
        {
            try
            {
                List<T> list = new List<T>();

                foreach (var row in table.AsEnumerable())
                {
                    T obj = new T();

                    foreach (var prop in obj.GetType().GetProperties())
                    {
                        try
                        {
                            PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name);
                            propertyInfo.SetValue(obj, Convert.ChangeType(row[prop.Name], propertyInfo.PropertyType), null);
                        }
                        catch
                        {
                            continue;
                        }
                    }

                    list.Add(obj);
                }

                return list;
            }
            catch
            {
                return null;
            }
        }

问题在于扩展方法调用会导致编译时错误。
The type T must be a reference type in order to use it as parameter compile time error.
那么,为了使扩展方法接受泛型作为参数,需要进行哪些更改?

DataTableToList方法有一个泛型约束T:class,但是另一个扩展方法没有这个约束。这就是为什么你看到了这个错误。你需要在那里也应用相同的约束。 - Chetan
2个回答

5

这个过程:

public IEnumerable<T>  ExecuteDataSet<T>(
    string storedProcName,
    IDictionary<string, IConvertible> parameters = null)

还需要类型参数。

where T : class, new()

2

在你的DAL方法中加入where T : class。编译器需要知道你DAL方法中的T能够满足扩展方法的类型约束。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接