c# - 由于使用 Task,使泛型函数异步在类型转换时失败
问题描述
以下是给定接口和类的结构:
public abstract class Entity
{ }
public class Group : Entity
{ }
public interface ICollectionPage<T>
{ }
public interface IGraphServiceGroupsCollectionPage : ICollectionPage<Group>
{ }
这里有两种使用这些接口的方法。一个是同步的,另一个是异步的,Task<T>
用于参数:
private static Task<IEnumerable<T>> GetAllAsync<T>(Task<ICollectionPage<T>> collectionTask)
where T : Entity
{
throw new NotImplementedException();
}
private static Task<IEnumerable<T>> GetAll<T>(ICollectionPage<T> collectionTask)
where T : Entity
{
throw new NotImplementedException();
}
如果我们尝试在代码中使用同步方法,一切都会按预期工作:
var collectionPage = (IGraphServiceGroupsCollectionPage)null;
var groups = GetAll(collectionPage);
但是如果我们尝试使用 async 方法,就会出现类型转换错误:
var collectionPageTask = (Task<IGraphServiceGroupsCollectionPage>)null;
var groupsFromAsync = GetAllAsync<IGraphServiceGroupsCollectionPage>(collectionPageTask);
错误 CS1503:参数 1:无法从 'System.Threading.Tasks.Task<RemotePowershell.IGraphServiceGroupsCollectionPage>' 转换为 'System.Threading.Tasks.Task<RemotePowershell.ICollectionPage<RemotePowershell.IGraphServiceGroupsCollectionPage>>'
关于如何在异步调用中避免此错误的任何想法?
完整代码:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
public interface IGraphServiceClient
{
}
public abstract class Entity
{
}
public class Group : Entity
{
}
public interface ICollectionPage<T>
{
}
public interface IGraphServiceGroupsCollectionPage : ICollectionPage<Group>
{
}
public class Program
{
private static Task<IEnumerable<T>> GetAllAsync<T>(Task<ICollectionPage<T>> collectionTask)
where T : Entity
{
throw new NotImplementedException();
}
private static Task<IEnumerable<T>> GetAll<T>(ICollectionPage<T> collectionTask)
where T : Entity
{
throw new NotImplementedException();
}
static void Main(string[] args)
{
var collectionPage = (IGraphServiceGroupsCollectionPage)null;
var groups = GetAll(collectionPage);
var collectionPageTask = (Task<IGraphServiceGroupsCollectionPage>)null;
var groupsFromAsync = GetAllAsync<IGraphServiceGroupsCollectionPage>(collectionPageTask);
}
}
更新原因:你为什么要这样做?
原因很简单。第一步,我们想为另一个异步方法编写一个扩展方法。此方法具有以下签名:
public interface IGraphServiceUsersCollectionRequest
{
public Task<IGraphServiceGroupsCollectionPage> GetAsync();
}
当我们喜欢这样称呼它时,我们喜欢这样做:
var request = (IGraphServiceUsersCollectionRequest)null;
var result = await request.GetAsync().GetAllAsync();
为了让它工作,我们需要一个扩展方法,它接受一个Task<IGraphServiceGroupsCollectionPage>
作为输入并返回一个Task<IEnumerable<Group>>
. 通过尝试构建此扩展方法,我们遇到了上述问题,我们将其归结为上述示例。
解决方案
您将需要使Task
参数更通用。
private static Task<IEnumerable<T>> GetAllAsync<T,T2>(Task<T> collectionTask)
where T : ICollectionPage<T2>
where T2 : Entity
{
throw new NotImplementedException();
}
...
var collectionPageTask = (Task<IGraphServiceGroupsCollectionPage>)null;
var groupsFromAsync = GetAllAsync<IGraphServiceGroupsCollectionPage,Entity>(collectionPageTask);
推荐阅读
- php - 为什么这个 json_encoded 字符串不返回第四个元素?
- java - JAVA - 如何制作自定义假期并跟踪它们
- android - 带有匕首的多模块项目:组件依赖于多个作用域组件
- mesh - meshlabserver:顶点属性传输
- webhooks - 收到 Zapier webhook 时发送什么响应
- java - 在 Apache Ignite 中禁用 SQL 转义
- javascript - 如何通过从数据库中获取像素值来为图像着色
- javascript - 用增强器扩展 Redux 的 createStore 的模式是什么?
- intellij-idea - 如何在 Intellij 中生成 package n 导入语句
- java - 如何结合两个 inRange() 函数来检测红色物体