Water Cooler v2
Water Cooler v2

Reputation: 33850

An equivalent of ConditionalAttribute for Task returning async methods

I'd like to write an async method but I'd like it to be callable only if the assembly is compiled with a specific compilation constant.

ONE WAY

One way I could do that is by using a pragma directive, i.e. a conditional compilation constant like so:

// 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

As you can see, it gets quite messy writing all of this.

ANOTHER WAY

The other way of doing this would be to use the ConditionalAttribute. However, from reading the documentation, it appears that the attribute is only applicable to methods that return void.

Had that constraint not been there, I would have used the attribute easily like so and that would have made the code so much more neater and nicer to look at and read:

// 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;  

}

Though I could have my async methods return void instead of Task, I'd feel very uncomfortable about doing that.

So, is there an equivalent of the ConditionalAttribute for methods that want to return a value? Is there one at least for those methods that would like to return just a Task?

Upvotes: 3

Views: 311

Answers (1)

Oleh Nechytailo
Oleh Nechytailo

Reputation: 2195

What do you expect to happen if you compile it with your condition? Should it return null? Or completed task? Or failed task?

The possible solution is to write your async methods like this:

#if FOO
public Task DoFooAsync() => Task.FromResult(0);
#else 
public Task DoFooAsync()
{
    //...
}
#endif

So your caller will get empty task in case you compiled the assembly with your conditional symbol.

Upvotes: 1

Related Questions