区分方法签名中的Task和Task<T>
Distinguish Task and Task<T> in method signature
我正在用这个签名创建一个方法
public async Task RunThisFunction(Func<Task> func)
现在这个方法的用户可以使用像这样的函数作为参数
public async Task GetThingsDone(){await DoSomething();}
这没什么好奇怪的,但你似乎也可以像这样发送函数
public async Task<string> GetString(){await return GetSomething();}
为什么会这样,我将如何编写签名以防止后者被发送到 RunThisFunction?
Task<T>
class继承了Task
class,所以returns一个Task<string>
返回一个[=11的方法=].您通常不能在需要更具体类型的地方提供不太具体的类型,因为它没有更具体类型所具有的附加成员。通常,您可以在期望不太具体的类型的地方提供更具体的类型,因为它将具有不太具体的类型所具有的所有成员。如果您有访问 Task
class 成员的代码,并且传入 Task<string>
,那么该代码将起作用,因为 Task<string>
对象具有所有这些成员。
您可以推断任务的通用参数:
public async Task<TTaskArg> RunThisFunction<TTaskArg>(Func<Task<TTaskArg>> func)
{
return await func();
}
您可以将其作为现有方法的重载,编译器将根据推断的类型选择正确的方法。
注意:虽然我没有在我的可运行示例中使用 async
关键字,但那是因为我的代码本质上是同步的。在实践中,您可能希望使用上面的 async
和 await
关键字。
如果您希望显示编译器警告,您可以添加 [Obsolete]
属性,例如:
[Obsolete("Please do not use tasks with a generic parameter.")]
public async Task<TTaskArg> RunThisFunction<TTaskArg>(Func<Task<TTaskArg>> func)
{
return await func();
}
也许(如果你需要的话)如果你想在运行时阻止它(成功)使用,你可以从方法中抛出一个 InvalidOperationException
。
正如 Alexei 所说,您还可以为过时的警告 (CS0612) 启用“警告作为错误”。有关如何执行此操作的说明,请参阅 here。请记住,您需要使用 CS0612 而不是 NU1605。
我正在用这个签名创建一个方法
public async Task RunThisFunction(Func<Task> func)
现在这个方法的用户可以使用像这样的函数作为参数
public async Task GetThingsDone(){await DoSomething();}
这没什么好奇怪的,但你似乎也可以像这样发送函数
public async Task<string> GetString(){await return GetSomething();}
为什么会这样,我将如何编写签名以防止后者被发送到 RunThisFunction?
Task<T>
class继承了Task
class,所以returns一个Task<string>
返回一个[=11的方法=].您通常不能在需要更具体类型的地方提供不太具体的类型,因为它没有更具体类型所具有的附加成员。通常,您可以在期望不太具体的类型的地方提供更具体的类型,因为它将具有不太具体的类型所具有的所有成员。如果您有访问 Task
class 成员的代码,并且传入 Task<string>
,那么该代码将起作用,因为 Task<string>
对象具有所有这些成员。
您可以推断任务的通用参数:
public async Task<TTaskArg> RunThisFunction<TTaskArg>(Func<Task<TTaskArg>> func)
{
return await func();
}
您可以将其作为现有方法的重载,编译器将根据推断的类型选择正确的方法。
注意:虽然我没有在我的可运行示例中使用 async
关键字,但那是因为我的代码本质上是同步的。在实践中,您可能希望使用上面的 async
和 await
关键字。
如果您希望显示编译器警告,您可以添加 [Obsolete]
属性,例如:
[Obsolete("Please do not use tasks with a generic parameter.")]
public async Task<TTaskArg> RunThisFunction<TTaskArg>(Func<Task<TTaskArg>> func)
{
return await func();
}
也许(如果你需要的话)如果你想在运行时阻止它(成功)使用,你可以从方法中抛出一个 InvalidOperationException
。
正如 Alexei 所说,您还可以为过时的警告 (CS0612) 启用“警告作为错误”。有关如何执行此操作的说明,请参阅 here。请记住,您需要使用 CS0612 而不是 NU1605。