Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 372
Water Cooler v2 Avatar asked May 03 '26 14:05

Water Cooler v2


1 Answers

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.

like image 114
Oleh Nechytailo Avatar answered May 06 '26 03:05

Oleh Nechytailo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!