代码之家  ›  专栏  ›  技术社区  ›  Codebadger

将泛型传递给扩展方法

  •  3
  • Codebadger  · 技术社区  · 8 年前

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

    执行查询后,结果存储在数据表中 必须转换为列表。

    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.
    

    那么,扩展方法要做哪些更改,以使其接受泛型作为参数?

    2 回复  |  直到 8 年前
        1
  •  5
  •   Jim    8 年前

    本程序:

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

    还需要类型参数。

    where T : class, new()
    
        2
  •  2
  •   Stewart Parry    8 年前

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