这是C#4中动态绑定的一个漏洞吗? [英] Is this a hole in dynamic binding in C# 4?
问题描述
我在 Fabio Maulo的文章中看到了一个非常有趣的文章一个>博客。如果您不想跳转到网址,则此处是代码和错误。我定义了一个新的通用类,如下所示:
公共类TableStorageInitializer< TTableEntity>其中TTableEntity:class,new()
{
public void Initialize()
{
InitializeInstance(new TTableEntity());
}
public void InitializeInstance(动态实体)
{
entity.PartitionKey = Guid.NewGuid()。ToString();
entity.RowKey = Guid.NewGuid()。ToString();
}
}
请注意,InitializeInstance接受一个参数,这是动态类型。现在要测试该类,我定义了另一个嵌套在主Program类中的类,如下所示:
类程序
{
static void Main(string [] args)
{
TableStorageInitializer< MyClass> x =新的TableStorageInitializer< MyClass>();
x.Initialize();
}
私有类MyClass
{
public string PartitionKey {get;组; }
公共字符串RowKey {get;组; }
public DateTime Timestamp {get;组; }
}
}
注意:内部类 MyClass被声明私人的。
现在,如果我运行此代码,我将得到 Microsoft.CSharp.RuntimeBinder.RuntimeBinderException 。
有趣的部分是,异常消息显示对象不包含PartitionKey的定义。
替代文字http://img697.imageshack.us/img697/4188/testdl.png
还请注意,如果您将嵌套类的修饰符更改为public,则代码将毫无问题地执行。那么你们认为到底发生了什么呢?请参阅任何文档-当然,如果您在任何地方都可以找到文档,您可能会发现?
活页夹试图计算出 accessible 类以将对象视为-在这种情况下,进行该调用的代码不会了解 我不知道C#4规范对此进行了详尽的记录-我知道我已经与Chris Burrows进行了电子邮件对话但是,因此详细信息可能在他的博客上的某处:)请记住,动态绑定具有随时间变化,因此有关RTM代码的最新帖子可能更准确。 我认为如果您将 动态类型周围存在各种陷阱。显式接口实现有一个类似的问题: 如果您传入数组,则会失败-因为尽管 活页夹试图将对象视为其具体类型,而不是 I've seen a very interesting post on Fabio Maulo's blog. Here's the code and the bug if you don't want to jump to the url. I defined a new generic class like so: Note that InitializeInstance accepts one parameter, which is of type dynamic. Now to test this class, I defined another class that is nested inside my main Program class like so: Note: the inner class "MyClass" is declared private. Also note that if you changed the modifier of the nested class to public, the code will execute with no problems. So what do you guys think is really happening under the hood? Please refer to any documentation -of course if this is documented anywhere- that you may find? The binder tries to work out an accessible class to treat the object as - in this case, the code making that call doesn't "know" about the I don't know how thoroughly this is documented in the C# 4 spec - I know I've had an email conversation about it with Chris Burrows though, so the details may be somewhere on his blog :) Bear in mind that the dynamic binding has changed over time, so more recent posts are likely to be more accurate with respect to the RTM code. I think that if you put There are various "gotchas" around dynamic typing. Explicit interface implementation has a similar problem: This will fail if you pass in an array - because although The binder tries to treat the object as its concrete type, not as 这篇关于这是C#4中动态绑定的一个漏洞吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! MyClass
类,因此它不会了解 PartitionKey $ c $ p>
PartitionKey
到私有类实现的公共接口中,该可以起作用-但您必须尝试一下。
public int Count(IList list)
{
int count1 = list.Count; //罚款
动态d =列表;
int count2 = d.Count; //应该可以,对吧?
}
IList.Count
存在,它是在数组中显式实现的-有点像这样:
string [] array = new string [10];
Console.WriteLine(array.Count); //不会编译
IList
,因此失败了。public class TableStorageInitializer<TTableEntity> where TTableEntity : class, new()
{
public void Initialize()
{
InitializeInstance(new TTableEntity());
}
public void InitializeInstance(dynamic entity)
{
entity.PartitionKey = Guid.NewGuid().ToString();
entity.RowKey = Guid.NewGuid().ToString();
}
}
class Program
{
static void Main(string[] args)
{
TableStorageInitializer<MyClass> x = new TableStorageInitializer<MyClass>();
x.Initialize();
}
private class MyClass
{
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public DateTime Timestamp { get; set; }
}
}
Now if i run this code I get a Microsoft.CSharp.RuntimeBinder.RuntimeBinderException on the line "entity.PartitionKey = Guide.NewGuid().ToString()".
The interesting part, though is that the message of the exception says "Object doesn't contain a definition for PartitionKey".
alt text http://img697.imageshack.us/img697/4188/testdl.pngMyClass
class, so it doesn't "know" about PartitionKey
either.PartitionKey
into a public interface that the private class implements, that may work - but you'd have to try it.public int Count(IList list)
{
int count1 = list.Count; // Fine
dynamic d = list;
int count2 = d.Count; // Should work, right?
}
IList.Count
exists, it's implemented explicitly in arrays - so it's a bit like this:string[] array = new string[10];
Console.WriteLine(array.Count); // Won't compile
IList
, hence the failure...