Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is something wrong with the dynamic keyword in C# 4.0?

There is some strange behavior with the C# 4.0 dynamic usage:

using System;  class Program {   public void Baz() { Console.WriteLine("Baz1"); }   static void CallBaz(dynamic x) { x.Baz(); }    static void Main(string[] args) {     dynamic a = new Program();     dynamic b = new { Baz = new Action(() => Console.WriteLine("Baz2")) };      CallBaz(a); // ok     CallBaz(b); // ok     CallBaz(a); // Unhandled Exception:     // Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:     // The name 'Baz' is bound to a method and cannot be used like a property   } } 

I'm using the Visual Studio 2010 Release Candidate.

Is this a bug? If it's true, will it be fixed in the Release?

like image 748
controlflow Avatar asked Feb 21 '10 17:02

controlflow


People also ask

Is it safe to use Dynamic C#?

It is definitely a bad idea to use dynamic in all cases where it can be used. This is because your programs will lose the benefits of compile-time checking and they will also be much slower.

Is C sharp dynamically typed?

Programming languages are sometimes divided into statically typed and dynamically typed languages. C# and Java are often considered examples of statically typed languages, while Python, Ruby and JavaScript are examples of dynamically typed languages.

What is difference between VAR and dynamic?

dynamic variables can be used to create properties and return values from a function. var variables cannot be used for property or return values from a function. They can only be used as local variable in a function.


2 Answers

I can confirm that this is indeed a bug. The quick description of what's going wrong here is as follows: In CallBaz, there is a single callsite that is invoked three times. That callsite is an InvokeMember, because that's the best guess the compiler can make given the C# syntax, despite that it could, in actuality, resolve to a GetMember followed by an Invoke.

During the second execution of the callsite, this is indeed the binding that the runtime finds. And so it produces a deferral to a GetMember followed by an invoke. The bug is that this deferral does not properly restrict itself to the case where the argument is the anonymous type. Therefore, in the third execution the deferral kicks in and the GetMember tries to bind to Program, which of course fails.

Thanks for finding this. As Eric points out, we're in a very late stage here, and it's becoming difficult to fix issues before we ship. But we also want to ship the right product. I'm going to do what I can to get this resolved, though I may not succeed. If you come up with anything else, please feel free to contact me. =)

UPDATE:

Although I can make no guarantee what the final version of VS 2010 and C# 4 will look like when it ships, I can say that I was successful in pushing this fix through. Today's release escrow build behaves correctly for your code. Barring some catastrophe, you will see this fixed at release. Thanks again. I owe you a beer.

like image 112
Chris Burrows Avatar answered Oct 02 '22 15:10

Chris Burrows


Looks suspicious. I'll send it off to testing and we'll see what they say.

Just to set expectations: if this is a bug, and it hasn't been found and fixed already, odds are good a fix will not get into the final release.

Thanks for bringing this to our attention!

like image 20
Eric Lippert Avatar answered Oct 02 '22 14:10

Eric Lippert