如何将匿名对象指定为通用参数?

时间:2015-10-02 14:53:04

标签: c# .net generics lambda

假设我有以下任务:

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

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

task的类型是什么?

实际上,结果是:System.Threading.Tasks.Task<'a>

其中'a是匿名类型:{ List<object> Data }

如何在不使用var的情况下明确说明此类型?

我已尝试Task<a'> task = ...Task<object> task = ...但无法管理它以进行编译。

为什么我需要这样做?

我有一个方法(UseApplicationCache<T>),它以Func<Task<T>>作为参数。

我还有一个变量cache,用户可能会设置为truefalse

如果true,则应调用上述方法,并且我的task应作为参数传递,如果false,我应执行task而不将其作为参数传递该方法的一个参数。

我的最终结果将是这样的:

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

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

3 个答案:

答案 0 :(得分:4)

  

如何明确说明此类型

你做不到。匿名类型没有名称,因此无法明确提及。

如果您创建通用帮助程序方法,则可以推断出匿名类型。在您的情况下,您可以这样做:

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

你可以这样做:

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

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

&#34;价值&#34;将自动推断TAnon

答案 1 :(得分:0)

我设法完成此操作而无需创建显式类型(如建议的注释):

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

答案 2 :(得分:0)

您可以dynamic键入以执行此操作:

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