How to specify anonymous object as generic parameter?

做~自己de王妃 提交于 2021-01-02 18:02:20

问题


Let's suppose I have the following task:

var task = _entityManager.UseRepositoryAsync(async (repo) => 
{
    IEnumerable<Entity> found = //... Get from repository

    return new 
    {
        Data = found.ToList()
    };
}

What is the type of task?

Actually, it turns out to be: System.Threading.Tasks.Task<'a>,

where 'a is anonymous type: { List<object> Data }

How can I explicitly state this type without using var?

I have tried Task<a'> task = ... or Task<object> task = ... but can't manage it to compile.

Why do I need to do this?

I have a method (UseApplicationCache<T>), that takes a Func<Task<T>> as a parameter.

I also have a variable cache that the user might set to true or false.

If true, the above said method should be called and my task should be passed as argument, if false, I should execute my task without giving it as an argument to the method.

My end result would be something like this:

Func<Task<?>> fetch = () => _entityManager.UseRepositoryAsync(async (repo) =>
{
     IEnumerable<Entity> found = //... Get from repository
     return new { Data = found.ToList() };
}

return await (cache ? UseApplicationCache(fetch) : fetch());

回答1:


How can I explicitly state this type

You cannot. An anonymous type has no name, hence cannot be explicitly mentioned.

The anonymous type can be inferred if you create a generic helper method. In your case, you can do:

static Func<TAnon> InferAnonymousType<TAnon>(Func<TAnon> f)
{
  return f;
}

With that you can just do:

var fetch = InferAnonymousType(() => _entityManager.UseRepositoryAsync(async (repo) =>
{
     IEnumerable<Entity> found = //... Get from repository
     return new { Data = found.ToList() };
}
));

return await (cache ? UseApplicationCache(fetch) : fetch());

The "value" of TAnon will be automatically inferred.




回答2:


I managed to accomplish this without having to create a explicit type (as the comments suggested):

Func<Task<object>> fetch = () => _entityManager.UseRepositoryAsync(async (repo) =>
{
    IEnumerable<Entity> found = //... Get from repository
    //I cast anonymous type to object
    return (object) new { Data = found.ToList() };
}

return await (cache ? UseApplicationCache(fetch) : fetch());



回答3:


You can you dynamic type to do this:

Func<Task<dynamic>> fetch = () => _entityManager.UseRepositoryAsync(async (repo) =>
{
   IEnumerable<Entity> found = //... Get from repository
   return new { Data = found.ToList() };
}


来源:https://stackoverflow.com/questions/32909980/how-to-specify-anonymous-object-as-generic-parameter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!