CancellationToken的默认参数
我有一些asynchronous代码,我想添加CancellationToken。 然而,有很多不需要的实现,所以我想有一个默认参数 – 也许是CancellationToken.None。 然而,
Task<x> DoStuff(...., CancellationToken ct = null) 
产量
types''的值不能用作默认参数,因为没有标准转换来键入'System.Threading.CancellationToken'
和
 Task<x> DoStuff(...., CancellationToken ct = CancellationToken.None) 
“ct”的默认参数值必须是编译时常量
有没有什么办法来取消CancellationToken的默认值?
事实certificate,以下工作:
 Task<x> DoStuff(...., CancellationToken ct = default(CancellationToken)) 
有没有什么办法来取消CancellationToken的默认值?
 不幸的是,这是不可能的,因为CancellationToken.None不是编译时间常量,这是可选参数中缺省值的要求。 
但是,可以通过重载方法而不是尝试使用默认参数来提供相同的效果:
 Task<x> DoStuff(...., CancellationToken ct) { //... } Task<x> DoStuff(....) { return DoStuff(...., CancellationToken.None); } 
 另一种select是使用Nullable<CancellationToken>参数,默认为null ,并在方法内部处理: 
 Task<x> DoStuff(...., CancellationToken? ct = null) { var token = ct ?? CancellationToken.None; ... } 
这里有几个解决scheme,按照一般善良的顺序排列:
  1.使用default(CancellationToken)作为默认值: 
 Task DoAsync(CancellationToken ct = default(CancellationToken)) { … } 
 在语义上, CancellationToken.None是默认的理想候选,但是不能这样使用,因为它不是一个编译时常量。  default(CancellationToken)是下一个最好的事情,因为它是一个编译时常量,并且正式logging为等效于CancellationToken.None 。 
  2.提供没有CancellationToken参数的方法重载: 
或者,如果您更喜欢方法重载超过可选参数(请参阅此问题和关于该主题的这个问题):
 Task DoAsync(CancellationToken ct) { … } // actual method always requires a token Task DoAsync() => DoAsync(CancellationToken.None); // overload producing a default token 
对于接口方法,使用扩展方法可以达到相同的效果:
 interface IFoo { Task DoAsync(CancellationToken ct); } static class Foo { public static Task DoAsync(this IFoo foo) => foo.DoAsync(CancellationToken.None); } 
这导致了一个更简洁的界面,并且使得实现者明确地写出转发方法的重载。
  3.使参数为空,并使用null作为默认值: 
 Task DoAsync(…, CancellationToken? ct = null) { … ct ?? CancellationToken.None … } 
我最不喜欢这个解决scheme,因为可空types会带来很小的运行时间开销,并且对取消标记的引用由于空合并运算符而变得更加冗长 。
Tofutim的回答是一种方式,但从评论我看到人们有问题。
在这种情况下,我确实build议可以有如下方法:
 Task<x> DoStuff(...., CancellationToken ct) { } 
并将其重载为:
 Task<x> DoStuff(....) { return DoStuff(...., CancellationToken.None); } 
 这样编译,因为CancellationToken.None的值在编译时不需要。