C # DLR, Datatype output with Dynamic keyword

Just asking:

Why the variable withOffset is displayed as dynamic like . Parse method returns Struct ?

dynamic str = "22/11/2013 10:31:45 +00:01"; var withOffset = DateTimeOffset.Parse(str); 

and after explicitly translating it back to Struct?

 dynamic str = "22/11/2013 10:31:45 +00:01"; var withOffset = DateTimeOffset.Parse((string)str); 

since the return type is DateTimeOffset.Parse is DateTimeOffset, and the compiler should know this. remembering that ever a method that is called at runtime always returns a DateTimeOffset.

The specifications indicate

Since your method accepts a dynamic argument, it is suitable for "dynamic binding"

bit suspicious.

What is the point of having such a specification? OR, in which case DateTimeOffset.Parse will not return STRUCT (forgetting DLR in a minute ..)?

The compiler should be smart if all methods / overloads in the class have the same return type in order to improve performance in the long run.

+5
c # dynamic-language-runtime
source share
2 answers

When you use dynamic , the whole expression is treated at compile time as a dynamic expression, which causes the compiler to treat everything as dynamic and get a binding at runtime.

This is explained in 7.2 C # language specification:

If dynamic expressions are not involved, C # is used by default for static binding, which means that the types of compound expressions are used in the selection process at compile time. However, when one of the constituent expressions in the above operations is a dynamic expression, the operation is instead dynamically linked.

This basically means that most of the operations (types are listed in section 7.2 of the specification) that have any element declared as dynamic will be evaluated as dynamic , and the result will be dynamic .


this is because in the line below str is dynamic

  dynamic str = "22/11/2013 10:31:45 +00:01"; var withOffset = DateTimeOffset.Parse(str); 

At compile time, str is dynamic; the str type is recognized only at runtime, which causes the compiler to treat withOffset as dynamic


you know that str is converted to a datetime structure, but for a compiler that it only recognizes at runtime ...

+4
source share

Here is a really good example of where your assumptions about the type of return start to go crazy.

 public class Bar { public string Foo(string value) { return value; } } 

As you can see here, Bar explicitly has an instance method Foo that takes a string and returns a string.

 public class Baz : Bar, IDynamicMetaObjectProvider { public DynamicMetaObject GetMetaObject(Expression parameter) { return new BazMetaObject(parameter, this); } } 

But now I have created a derived class that also implements IDynamicMetaObjectProvider . This is the interface that C # uses to get a DynamicMetaObject that defines how dynamic calls are connected at runtime. For example:

 public class BazMetaObject : DynamicMetaObject { public BazMetaObject(Expression expression, Baz value) : base(expression, BindingRestrictions.Empty, value) { } public override DynamicMetaObject BindInvokeMember( InvokeMemberBinder binder, DynamicMetaObject[] args) { if (binder.Name == "Foo") { return new DynamicMetaObject( Expression.Convert( Expression.Call( typeof (BazMetaObject).GetMethod("DynamicFoo") ), typeof (object) ), BindingRestrictions.GetTypeRestriction( this.Expression, this.LimitType ) ); } return base.BindInvokeMember(binder, args); } public static int DynamicFoo() { return 1234; } } 

This overload of DynamicMetaObject will capture any calls to Foo and dynamically redirect them to DynamicFoo , which has a completely different signature - including that it returns int , not string .

So, if you did this ...

 dynamic value = "Hello, world!"; Bar bar = new Baz(); var returnValue = bar.Foo(value); 

... the returnValue value at run time will be 1234 , not "Hello, world!" .

Now, in the real world, this is insanely evil. Although you can completely restore functions that are expected to do something in a certain way, doing something funny like this will only confuse people along the way. This, as they say, is quite possible in the CLR.

TL; DR: When you use dynamic , you cannot always be sure what you think is right.

+1
source share

All Articles