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?
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);