未使用泛型

时间:2016-04-29 09:16:32

标签: c# generics types

我的代码存在很大问题,负责从数据库加载数据并将其转换为自定义数据模型对象列表。

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

以下是我现在所拥有的内容,但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();
        }
    }

1 个答案:

答案 0 :(得分:1)

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

        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
        }