2016-04-29 54 views
0

我的代码负责从数据库加载数据并将其转换为我的自定义数据模型对象的列表时出现严重问题。未能缩短使用泛型的类似函数调用

由于有很多数据表,我将有许多列表,我不想真正创建和使用复制/粘贴手动分配它们,只是修改类型。

这是我现在所拥有的,但LoadAllModelListsAsProperties方法中有关于Type与泛型类型参数之间的转换失败的错误。

我不明白如何解决这种不兼容性Type<T>。我该怎么办?

public class DataProvider 
{ 
    private Dictionary<Type, object> Memory { get; set; } 
    private static Dictionary<Type, Type> AllModelTypes { get; } 


    static DataProvider() 
    { 
     AllModelTypes = new Dictionary<Type, Type>() 
     { 
      { typeof(AreaModel),    typeof(Areas) }, 
      { typeof(GroupModel),    typeof(Groups) }, 
      /* many more.... */ 
      { typeof(TownModel),    typeof(Towns) } 
     }; 
    } 


    public DataProvider() 
    { 
     // fill Memory dictionary with empty list instances 
     foreach (Type ModelType in AllModelTypes.Keys) 
     { 
      Memory.Add(ModelType, Activator.CreateInstance(
            typeof(List<>).MakeGenericType(ModelType))); 
     } 
    } 


    public List<TModel> GetModelList<TModel>(Type modelType) 
     where TModel : ModelBase 
    { 
     // get the list from memory that matches the given type 
     return (List<TModel>)Memory[modelType]; 
    } 

    public void LoadAllModelListsAsProperties() 
    { 
     var filter = (c) => true; // just simplified as example 

     foreach (KeyValuePair<Type, Type> item in AllModelTypes) 
     { 
      Type modelType = item.Key; 
      Type linqType = item.Value; 

      List<ModelBase> modelList = GetModelList<modelType>(modelType); 
      // !!!! ^^^^^^ error that it can't implicitly convert 
      //    List<modelType> to List<Modelbase> 

      modelList.Clear(); 
      modelList.AddRange(LoadListOfModels<linqType, modelType>(filter, 
             modelType.ModelFactoryFromLinq); 
      // !!!! ^^^^^^ error that "linqType"/"modelType" are variables, 
      //    but get used like types; and that 
      //    Type has no definition for "ModelFactoryFromLinq 
     } 

     // normally I would have to call something like that for every list type: 
     //AreaModels = LoadListOfModels<Areas, AreaModel>(
     // filter, AreaModel.ModelFactoryFromLinq); 
     //GroupModels = LoadListOfModels<Groups, GroupModel>(
     // filter, GroupModel.ModelFactoryFromLinq); 
     //TownModels = LoadListOfModels<Towns, TownModel>(
     // filter, TownModel.ModelFactoryFromLinq); 
    } 


    public List<TModel> LoadListOfModels<TLinq, TModel>(
     Func<TLinq, bool> filter, 
     Func<TLinq, TModel> modelFactory 
     ) 
     where TLinq : class, ILinqClass 
     where TModel : ModelBase 
    { 
     using (LinqToSqlDataContext dc = new LinqToSqlDataContext()) 
     { 
      return dc.GetTable<TLinq>() 
       .Where(filter) 
       .Select(modelFactory) 
       .ToList(); 
     } 
    } 
+0

你必须使用[反思](https://msdn.microsoft.com/en-us/library/ms173183.aspx)。不过,我建议你将'LoadAllModelListsAsProperties'(适用于单一类型的逻辑)中的一些逻辑封装到通用方法中。这样,您可以最大限度地减少需要执行的反射量。 –

+0

什么是'ModelFactoryFromLinq'? –

+0

@YacoubMassad这是一个静态方法,每个模型类都会返回该类的新实例。 –

回答

1
  1. 不能使用类型变量类型
  2. 您可以使用基类类型=>GetModelList<ModelBase>(modelType);
  3. 你不需要时,你传递正确的对象使用类型的方法LoadListOfModels方法。编译器将从参数中确定泛型类型。
  4. 什么是ModelFactoryFromLinq?如果它是一个属性,你只需要使用反射或者你可以创建一个方法来返回正确的func < ..>通过给定的类型。如果它是一个方法试试这个:

    foreach (KeyValuePair<Type, Type> item in AllModelTypes) 
        { 
         Type modelType = item.Key; 
         Type linqType = item.Value; 
    
         List<ModelBase> modelList = GetModelList<ModelBase>(modelType); 
         // !!!! ^^^^^^ error that it can't implicitly convert 
         //    List<modelType> to List<Modelbase> 
    
         modelList.Clear(); 
         var ModelFactoryFromLinq = modelType.GetMethod("ModelFactoryFromLinq"); 
         modelList.AddRange(LoadListOfModels(filter, modelFactoryFromLinq)); 
         // !!!! ^^^^^^ error that "linqType"/"modelType" are variables, 
         //    but get used like types; and that 
         //    Type has no definition for "ModelFactoryFromLinq 
        }