如何将匿名对象指定为泛型参数

本文关键字:泛型 参数 对象 | 更新日期: 2023-09-27 18:15:47

假设我有以下任务:

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

如何将匿名对象指定为泛型参数

如何显式声明此类型

你不能。匿名类型没有名称,因此不能显式地提及。

如果创建泛型助手方法,则可以推断匿名类型。在您的情况下,您可以这样做:

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

自动推断TAnon的"value"

我设法完成了这一点,而不必创建显式类型(如注释所建议的):

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

您可以将dynamic类型设置为:

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