我想写一个async
方法,但我希望只有在使用特定的编译常量编译程序集时才能调用它。
ONE WAY
我能做到的一种方法是使用pragma指令,即条件编译常量,如下所示:
// Callee
#if FOO
public async Task DoFooAsync()
{
...
}
#end if
// Caller 1
#if Foo
// fire and forget
DoFooAsync();
#endif
// Caller 2
#if Foo
public async Task<T> DoWork<T>()
{
T returnValue = default(T);
// fire but don't forget
var fooTask = DoFooAsync();
// Prepare return value
returnValue = ...;
// Not terribly important but what if the caller wants
// to find out
if (fooTask.Status == Faulted)
{
// do something about it
}
}
#endif
正如你所看到的,编写所有这些内容会非常混乱。
另一种方式
另一种方法是使用ConditionalAttribute
。但是,通过阅读文档,该属性似乎仅适用于返回void
的方法。
如果没有那个约束,我会很容易地使用这个属性,这会让代码变得更整洁,更好看和阅读:
// Callee
[Conditional("FOO")]
public Task DoFooAsync() { ... }
// Caller
public async Task<T> DoWork<T>()
{
// fire and forget
DoFooAsync();
// fire but would like to know what happened
var fooTask = DoFooAsync();
T t = GetTee();
if (fooTask.IsFaulted) { ... }
return t;
}
虽然我可以让我的async
方法返回void
而不是Task
,但我对此感到非常不舒服。
那么,对于想要返回值的方法,是否有等效的ConditionalAttribute
?是否至少有一个方法只想返回Task
?
答案 0 :(得分:2)
如果你按照自己的条件进行编译,你会发生什么?它应该返回null吗?还是完成了任务?或者任务失败?
可能的解决方案是编写这样的异步方法:
#if FOO
public Task DoFooAsync() => Task.FromResult(0);
#else
public Task DoFooAsync()
{
//...
}
#endif
因此,如果使用条件符号编译程序集,则调用者将获得空任务。