问题
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