Having a dynamic call inside a function prevents static context checking. Why?
I have the following code. Using Visual Studio 2013. Notice the dynamic function call within the function
class Someclass
{
public static string[] BuildParametersString(ISomeInterface obj1, ISecondInterface obj2)
{
//.....
var dt = obj1.GetDate();//this returns a dynamic type.
SomeFunc(dt);//Run time error
}
private string SomeFunc(DateTime somedate)
{
//......
}
}
Runtime error (in SomeFunc (dt);): An object reference is required for a non-static field, method or property.
If I replace the following code
var dt = obj1.GetDate();//this returns a dynamic type.
with this
DateTime dt = DateTime.Now;
I am getting compiler error (in SomeFunc (dt))
It is not possible to access the static SomeFunc method in a static context.
Any explanation for the behavior?
source to share
Overload resolution is still performed at compile time dynamic
to provide a list of possible functions that could be called. At run time, the list is narrowed to the maximum according to the actual type dynamic
.
As per the spec, however, overload resolution only considers the number and types of arguments - not, static
or even availability. According to some quick tests, it seems that the order of operations at compile time is:
- Availability check
- Overload resolution
- Static check
Since it dynamic
affects overload resolution (step # 2), but cannot narrow down to the best possible candidate at compile time, it looks like check static
(# 3) is also delayed until runtime.
I do not see in theory any reason to believe that the steps cannot be reordered (NB: I donβt know if there is a relevant specification to consider) or that step # 3 cannot be performed (at compile time) against all possible candidates. out of "dynamic" overload resolution to ensure that at least one candidate remains.
Even if this is not a real mistake 1, I do think it is contrary to a design principle dynamic
- which I have always understood to only postpone what you have no choice but to postpone.
UPDATE: note that the C # 6 compiler in LINQPad 5 / VS2015 now specifies this at compile time; although the order of operations doesn't seem to have changed.
1 Section 7.6.5.1 of the C # 5 Method Specification (Method Calls) specifies that "final validation" (including static validation) occurs after overload resolution; Section 7.5.4 (Checking the Time of Dynamic Overload Resolution at Compile Time) only indicates that partial input and partial applicability (overload resolution) output routines are performed for method calls with dynamic arguments.
source to share
Since it
EDIT: This is not actually what Chris Sinclair points out, you can use SomeFunc(DateTime)
has DateTime
a parameter type, you cannot give it an object dynamic
. It is waiting DateTime
, so you have to get it out. dynamic
like this. The rest of my answer still holds true though
You also cannot access an instance method SomeFunc(DateTime)
from a static method, as an instance method can rely on instance variables that do not exist in a static context. Either make it SomeFunc(DateTime)
static (if possible) or make BuildParametersString(ISomeInterface, ISecondInterface)
an instance method (or just return the result from GetDate()
) and send it as an argument SomeFunc(DateTime)
from client code.
I don't know if this is just an example to show the point, but I would also seriously reconsider using dynamic variables in this case. Are you getting anything from this? They should usually be avoided at all costs as they only complicate matters and you have lost all compile-time checks.
source to share