Reputation: 33
Can someone explain to me why the compiler does not check the return type of a function if a dynamic variable is used as an argument to a method call?
class Program
{
static void Main(string[] args)
{
// int a = GetAString(1); // Compiler error CS0029 Cannot impilicitly convert type 'string' to 'int'
dynamic x = 1;
int b = GetAString(x); // No compiler error -> Runtime Binder Exception
// int c = (string)GetAString(x); // Compiler error CS0029 Cannot impilicitly convert type 'string' to 'int'
}
static string GetAString(int uselessInt)
{
return "abc";
}
}
Upvotes: 3
Views: 135
Reputation: 29233
In the general case, the candidates aren't necessarily as straightforward as yours. For example, consider these two methods:
string M(string a) => a;
char[] M(char[] a) => a;
What should this code suggest as the type of the last variable?
dynamic d = SomeExpression();
var s = M(d);
At this point, the designers of C# would have to make a choice:
dynamic
arguments is also dynamic
itself.IEnumerable<char>
).The latter option is essentially what you're describing in your question. The C# designers went with the former option. Possible reasons for that design decision could be:
dynamic
in an expression, then it's more likely than not that you'll want to keep using dynamic
on any dependent expressions, until you explicitly opt out of it again.dynamic
to enable multiple dispatch, so they didn't want to encourage it further by including provisions for static typing.dynamic
implemented) and they decided the other option wasn't worth more time or effort.Upvotes: 1
Reputation: 62542
By using dynamic
the compiler will generate a call site anywhere you use a dynamic parameter. This call site will attempt to resolve the method at runtime, and if it cannot find a matching method will raise an exception.
In your example the call site examines x
and sees that it is an int
. It then looks for any methods called GetAString
that take an int
and finds your method and generates code to make the call.
Next, it will generate code to attempt to assign the return value to b
. All of this is still done at runtime as the use of the dynamic variable has made the entire expression require runtime evaluation. The call site will see if it can generate code to assign a string
to an int
, and as it cannot it will raise an exception.
As an aside, your example doesn't make a lot of sense as you seem to want to assign a string
to an int
Your GetAsString
method is even returning a non-numeric value so it's never going to assign to an int
. If you write:
dynamic x = 1;
string b = GetAsString(x);
Then everything should work.
Upvotes: 2