C#4.0中的dynamic关键字有问题吗?
C#4.0的动态使用有一些奇怪的行为:C#4.0中的dynamic关键字有问题吗?,c#,caching,dynamic,C#,Caching,Dynamic,C#4.0的动态使用有一些奇怪的行为: 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 Ac
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
}
}
我正在使用VisualStudio2010候选版本
这是虫子吗?如果这是真的,它会在发行版中被修复吗?同样的事情也会发生在我身上,我建议你报告它。这看起来像是一个严重的错误 请注意,如果您使用
ExpandoObject
而不是匿名类型,则可以正常工作:
using System;
using System.Dynamic;
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 ExpandoObject();
b.Baz = new Action(() => Console.WriteLine("Baz2"));
CallBaz(a); // ok
CallBaz(b); // ok
CallBaz(a); // ok
}
}
所以这个问题似乎只针对匿名对象
显然,在对
CallBaz(a)
的第二次调用中,DLR仍然尝试将Baz
作为属性访问,因为它是匿名类型的属性。我怀疑C#binder对调用解析进行了一些缓存,以获得更好的性能,但在这种情况下,它显然已损坏…看起来可疑。我会把它送去测试,看看他们怎么说
只是为了设定期望值:如果这是一个bug,并且它还没有被发现和修复,那么很有可能修复不会进入最终版本
谢谢你让我们注意到这一点 我可以确认这确实是一个bug。这里的错误简要描述如下:在CallBaz中,有一个调用三次的callsite。这个callsite是一个InvokeMember,因为在给定C#语法的情况下,这是编译器能够做出的最佳猜测,尽管它实际上可以解析为一个GetMember,然后是一个Invoke 在调用站点的第二次执行期间,这确实是运行时找到的绑定。因此,它产生一个对GetMember的延迟,后跟一个调用。错误在于,这种延迟没有适当地将自身限制在参数为匿名类型的情况下。因此,在第三次执行中,延迟开始,GetMember尝试绑定到程序,当然失败了 谢谢你找到这个。正如Eric指出的,我们现在处于非常晚的阶段,在发货之前解决问题变得越来越困难。但我们也希望运送正确的产品。我将尽我所能解决这个问题,尽管我可能不会成功。如果您还有其他想法,请随时与我联系。=) 更新:
虽然我不能保证VS2010和C#4的最终版本在发布时会是什么样子,但我可以说我成功地完成了这个修复。今天的发行版托管构建对于您的代码来说是正确的。除非发生灾难,否则您将在发布时看到这一点。再次感谢。我欠你一杯啤酒。埃里克·利珀特在哪里:我也可以复制它。。。对CallBaz(a)的第一个调用工作正常,第二个调用失败。它看起来确实像一个bug,而且是一个严重的bug…很有趣。我把一封电子邮件放到了一个合适的列表中——希望它很快会引起一些注意。ControlFlow,您应该认真考虑加入.NET/C测试团队。这是您报告的第三期,Eric确认这是一个bug。@Yogi True…谁是ControlFlow?它是C#spec的拟人化人格吗?