C# 由于使用任务,使泛型函数异步在类型转换时失败<;T>;
以下是给定接口和类的结构:C# 由于使用任务,使泛型函数异步在类型转换时失败<;T>;,c#,type-inference,C#,Type Inference,以下是给定接口和类的结构: public abstract class Entity { } public class Group : Entity { } public interface ICollectionPage<T> { } public interface IGraphServiceGroupsCollectionPage : ICollectionPage<Group> { } 但如果尝试使用async方法,则会出现类型转换错误: var coll
public abstract class Entity
{ }
public class Group : Entity
{ }
public interface ICollectionPage<T>
{ }
public interface IGraphServiceGroupsCollectionPage : ICollectionPage<Group>
{ }
但如果尝试使用async方法,则会出现类型转换错误:
var collectionPageTask = (Task<IGraphServiceGroupsCollectionPage>)null;
var groupsFromAsync = GetAllAsync<IGraphServiceGroupsCollectionPage>(collectionPageTask);
为了实现这一点,我们需要一个扩展方法,它将
任务
作为输入,并返回任务
。通过尝试构建此扩展方法,我们遇到了上述问题,并将其归结为上述示例。您需要使任务
参数更通用
private static Task<IEnumerable<T>> GetAllAsync<T,T2>(Task<T> collectionTask)
where T : ICollectionPage<T2>
where T2 : Entity
{
throw new NotImplementedException();
}
私有静态任务GetAllAsync(任务收集任务)
其中T:ICollectionPage
其中T2:实体
{
抛出新的NotImplementedException();
}
var collectionPageTask=(Task)null;
var groupsFromAsync=GetAllAsync(collectionPageTask);
您需要使任务
参数更通用
private static Task<IEnumerable<T>> GetAllAsync<T,T2>(Task<T> collectionTask)
where T : ICollectionPage<T2>
where T2 : Entity
{
throw new NotImplementedException();
}
私有静态任务GetAllAsync(任务收集任务)
其中T:ICollectionPage
其中T2:实体
{
抛出新的NotImplementedException();
}
var collectionPageTask=(Task)null;
var groupsFromAsync=GetAllAsync(collectionPageTask);
问题在于任务(作为一个类)是不变的。根据问题中的评论:
IGraphServiceGroupsCollectionPage
实现了ICollectionPage
,该方法可用于任务
您希望任务
与任务
兼容。事实并非如此。你可以很简单地说:
task1=null;
任务task2=task1;
这会产生以下错误:
错误:无法将类型“System.Threading.Tasks.Task”隐式转换为“System.Threading.Tasks.Task”
此外,本电话:
GetAllAsync(collectionPageTask)
。。。为T
提供了一个显式类型参数IGraphServiceGroupsCollectionPage
,该参数的类型为ICollectionPage
,因此编译器试图将该参数转换为任务
问题是任务(作为一个类)是不变的。根据问题中的评论:
IGraphServiceGroupsCollectionPage
实现了ICollectionPage
,该方法可用于任务
您希望任务
与任务
兼容。事实并非如此。你可以很简单地说:
task1=null;
任务task2=task1;
这会产生以下错误:
错误:无法将类型“System.Threading.Tasks.Task”隐式转换为“System.Threading.Tasks.Task”
此外,本电话:
GetAllAsync(collectionPageTask)
。。。为T
提供了一个显式类型参数IGraphServiceGroupsCollectionPage
,该参数的类型为ICollectionPage
,因此编译器试图将该参数转换为任务
.返回类型不同,这与异步和任务无关。错误抱怨将IGraphServiceGroupsCollectionPage
转换为ICollectionPage
为什么GetAllAsync
接受Task collectionTask
而不是ICollectionPage
?为什么不等待前面的任务并将结果传递给方法?即使您使用了.ContinueWith
,您也会将结果传递给任何后续方法。是的,您将无法将参数强制放入“任务”中,就像那样异步调用没有区别。async
关键字不会影响任何东西,它只是一个标记,告诉编译器该方法可以使用wait
。不过,将任务作为参数传递给另一个方法的情况极为罕见。为什么要这样做?忘记异步,这是一个类型问题而不是TPL问题返回类型不同,这与异步和任务没有什么关系。错误抱怨将IGraphServiceGroupsCollectionPage
转换为ICollectionPage
为什么GetAllAsync
接受Task collectionTask
而不是ICollectionPage
?为什么不等待前面的任务并将结果传递给方法?即使您使用了.ContinueWith
,您也会将结果传递给任何后续方法。是的,您将无法将参数强制放入“任务”中,就像那样异步调用没有区别。async
关键字不会影响任何东西,它只是一个标记,告诉编译器该方法可以使用wait
。不过,将任务作为参数传递给另一个方法的情况极为罕见。你为什么要这样做?忘记异步,这是一个类型问题而不是TPL问题。我的答案是“这就是为什么它目前无法编译”。@JonSkeet-alley-oop,slamdunkYes,这是有效的,但现在类型推断已经消失了。因此,如果您试图调用此方法而不显式指定泛型参数,则会失败。@Oliver这确实是问题所在,请参阅Jon的解释,为什么不能以其他方式执行此操作感谢您提供了“这是要做的事”-我的回答提供了“这就是它目前无法编译的原因”。@JonSkeet alley oop,slamdunkYes,这很有效,但是现在类型推断已经不存在了。因此,如果您试图调用此方法而不显式指定泛型参数,则会失败。@Oliver这确实是问题所在,请参阅jons解释,否则无法执行此操作
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();
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);