2

Let's have the following simplified code:

UPDATE: The methods actually returns an object with generic type <T>.

void Main()
{
    Foo<object>(null);
}

Bar<T> Foo<T>(T value) // first
{
    Console.WriteLine("Value: {0}", value);
    // return new Bar<T> ...
}

async void Foo<T>(Task<T> task) // second
{
    Console.WriteLine("Value from task: {0}", await task);
    // return new Bar<T> ...
}

This code fails in runtime: Object reference not set to an instance of an object. I have realized that compiler chooses the second overload of Foo with Task<T> argument. And therefore it fails when trying to await null.

Maybe it is correct behavior according the C# spec, but it can cause real troubles, since it is not the right overload that programmer wanted. If it is not a bug in specification or in compiler, shouldn't compiled show some warning in similar cases? What is the most convenient way to tell the compiler to choose the first overload?

TN.
  • 18,874
  • 30
  • 99
  • 157

2 Answers2

2

In overload resolution, if null is passed, then is chosen the method with the "most" derived type. In your case, Task inherits from Object, so async void Foo<T>(Task<T> task) is called.

If you called Foo<string>(null); then the compiler gave an error because Task doesn't inherit from string (nor string inherits from Task)

Matteo Umili
  • 3,412
  • 1
  • 19
  • 31
  • I have updated the code. Actually I cannot call the `Foo` as I would get an object with a different generic argument. – TN. Jul 16 '15 at 12:56
1

Overloads are chosen based on the compile time type, not the run time type, so something like this should work:

void Main()
{
    object value = null;
    Foo<object>(value);
}

As mentioned in a deleted answer, you can also just cast it to an object first:

Foo<object>((object)null);

or

Foo<object>(null as object);
Jezzamon
  • 1,453
  • 1
  • 15
  • 27
  • The simplest way is `Foo((object)value)`. Someone post this there, but then deleted the answer. So, now your answer is the closest. – TN. Jul 16 '15 at 13:07