运行时类型<t>的通用方法,并将结果存储在IEnumerable <t> </t> </t>中

时间:2014-05-30 10:42:44

标签: c# generics dynamic reflection

在将其标记为重复之前,请注意我已阅读所有这些问题,包括Jon Skeet的答案,但我仍有问题。 我已经完成的链接以及其他一些我未在此处列出的内容:

Instantiate object with reflection and dynamic arguments count

Instructing a generic to return an object of a dynamic type

Is there a way not to use dynamic when instantiating a type that inherits from generic?

我搜索了同样的问题并意识到在运行时提供类型T是不可能的,因为通用类型T必须在编译时知道。我理解这一点,但我有以下情况:

基本上我想这样做:

public IEnumerable<T> GetListing<T>(string entityName)
{
    Entity entity = new Entity { Name = entityName, Action = "Select" };

    ResponsePacket<T> entityViewModel = new ResponsePacket<T>();

    entityViewModel.Records = myHttpClient.GetAllEntities<T>(entity, "10", "0").Content;

    return entityViewModel.Records.AsEnumerable();
}

并称之为:

public IEnumerable<myType> CallListing(string entityName)
{
    Type myType = {get type of entityName through some method eg User}
    IEnumerable<myType> result = GetListing<myType>;
    return result;
}

现在我已经读过这个不能实现没有反射这意味着我必须创建一个GetListing<>的实例,然后通过反思来告诉它<T>

我的问题是即使我使用反射来创建GetListing<myType>的实例并在运行时通过反射调用它,如何在GetListing<T>中获得IEnumerable<myType>的返回结果}?反射是否也会在运行时提供IEnumerable<myType>的结果?

据我所知,Reflection的返回结果是一个对象,如何将其转换为IEnumerable<myType>,我不能将其转换为IList:

IList returnedresult = (IList)returnedResult因为我的网格/视图页面需要IEnumerable<myType> 的模型,即IEnumerable<User>IEnumerable<Roles>,我希望通过反思。我必须将模型传递给我的视图@model IEnumerable<GridModel>,其中gridmodel需要IEnumerable<myType>

我还读到动态是这里的方式,但我不知道如何。我将如何使用动态实现我正在寻找的东西?我没有线索。请告诉我是否有办法将反映方法的返回结果存储在IEnumerable<myType>中。

如果这些都无法实现,那么请告诉我如何以其他方式实现这一目标。

我不知道编译时的实体类型,否则会有很多代码复制&amp;如果我有100个实体,我想为其调用GetListing(),我将不得不编写GetUserListing,GetRolesListing,Get ... Listing()然后我必须显式调用GetListing<User>,{{1}来自GetUserListing,GetRolesListing方法,这些方法违背了目的。

1 个答案:

答案 0 :(得分:1)

我认为这就是你要照顾的事情:

void Main()
{
    Console.WriteLine(Get<int>("System.Int32").ToString());
    Console.WriteLine(Get<string>("System.String").ToString());
    Console.WriteLine(Get<double>().ToString());
    Console.WriteLine(Get<long>().ToString());
}

public Type TypeResolver(string type)
{
    return Type.GetType(type);
}

public IEnumerable<T> Get<T>(string typeName)
{   
    var type = TypeResolver(typeName);
    var entityStore = new EntityStore();
    return entityStore.GetType().GetMethod("GetAll").MakeGenericMethod(type).Invoke(entityStore, null) as IEnumerable<T>;
}

public IEnumerable<T> Get<T>()
{
    var entityStore = new EntityStore();
    return entityStore.GetType().GetMethod("GetAll").MakeGenericMethod(typeof(T)).Invoke(entityStore, null) as IEnumerable<T>;
}

public class EntityStore
{
    public IEnumerable<T> GetAll<T>()
    {
        return new List<T>();
    }
}