zeppelin
zeppelin

Reputation: 451

Generic method of type <T> at runtime AND storing result in IEnumerable<T>

Before marking it as duplicate, Please note that I have read all these questions including Jon Skeet's answer but still I have an issue. Links I have gone through and a few more I'm not listing here:

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?

I have searched the same question and realized that providing type T at runtime is not possible because Generic type T must be known at compile time. I understand this but I have the following scenario:

Basically I want to do this :

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();
}

And call it like this :

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

NOW I have read that this cannot be achieved without reflection which means I have to create an instance of GetListing<> and then tell it through reflection about the <T>.

My problem is even if I use reflection to create an instance of GetListing<myType> and invoke it at runtime through reflection, How do I get the returned result of GetListing<T> in IEnumerable<myType> ? Will reflection also provide the result of IEnumerable<myType> at runtime ?

From what I know, the returned result of Reflection is an object, How do I cast it to IEnumerable<myType>, I cannot cast it to IList like this:

IList returnedresult = (IList)returnedResult because my Grid/View page needs a model of IEnumerable<myType> i.e IEnumerable<User> OR IEnumerable<Roles> which I am hoping to get through reflection. I have to pass a model to my view @model IEnumerable<GridModel> where gridmodel will need IEnumerable<myType>.

I have also read that dynamic is the way to go here, but I dont know how. How will I achieve what I am looking for using dynamic? I have no clue. Please tell me if there is a way to store the returned result of reflected method in an IEnumerable<myType>.

If both of these cannot be achieved then please tell me how can I achieve this in some other way.

I dont know the Type of entity at compile time otherwise there would be lots of code replication & if I have 100 entities for which I want to call GetListing() for, I would have to write GetUserListing, GetRolesListing, Get...Listing() and then I would have to explicitly call GetListing<User>, GetListing<Roles> from inside the GetUserListing, GetRolesListing methods which defeats the purpose.

Upvotes: 0

Views: 264

Answers (1)

Zache
Zache

Reputation: 1043

I think this is what you are looking after:

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>();
    }
}

Upvotes: 1

Related Questions