为什么C#dynamic解析内部属性而不解析方法?

我有一个包含以下类的库:

public interface IEntity { string Foo { get; } void Bar(int x); } public class EntityFactory { public static IEntity createEntity() { return new Entity(); } } internal class Entity : DynamicObject, IEntity { public void Bar(int x) { Console.WriteLine("inside Bar"); Console.WriteLine("bar {0}", x); } public string Foo { get { Console.WriteLine("inside Foo getter"); return "foo"; } } public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) { Console.WriteLine("inside TryInvokeMember(binder.Name = '{0}')", binder.Name); return base.TryInvokeMember(binder, args, out result); } public override bool TryGetMember(GetMemberBinder binder, out object result) { Console.WriteLine("inside TryGetMember(binder.Name = '{0}')", binder.Name); if (binder.Name == "SomeVar") { result = 42; return true; } return base.TryGetMember(binder, out result); } } 

以及使用它们的程序:

 public static void Main(string[] args) { dynamic entity = EntityFactory.createEntity(); Console.WriteLine("entity.Foo = {0}", entity.Foo); entity.Bar(24); Console.WriteLine("entity.SomeVar = {0}", entity.SomeVar); } 

输出是

 inside Foo getter entity.Foo = foo inside TryInvokeMember(binder.Name = 'Bar') inside TryGetMember(binder.Name = 'Bar') 

然后我收到一个例外

 Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: `EntityLib.Entity.Bar(int)' is inaccessible due to its protection level 

为什么动态对象直接访问属性Foo ,但无法调用方法Bar并使用TryInvokeMemberTryGetMember代替? 它们具有相同的访问修饰符。

更新:在Mono上观察到所描述的行为。 访问Foo属性时,Microsoft已失败。 以下代码按预期工作:

 public static void Main(string[] args) { var entity = EntityFactory.createEntity(); entity.Bar(24); Console.WriteLine("entity.Foo = {0}", entity.Foo); dynamic e = entity; Console.WriteLine("entity.SomeVar = {0}", e.SomeVar); } 

这是一个错误还是一个function是由微软决定的。 但是,我希望将变量转换为动态不应限制访问。

  internal class Entity .... 

动态关键字不是限制可访问性的变通方法。 Entity类被声明为internal ,因此尝试从不属于实体所在的程序集的代码调用其Bar()方法将被绑定器拒绝,该消息几乎没有想象:

由于其保护级别,EntityLib.Entity.Bar(int)’无法访问

获得成功的合理方法是将Entity类声明为public 。 如果由于某种原因这是一个问题,那么你可以用reflection破坏规则。 你需要使用BindingFlags.NonPublic | Type.GetMethod()调用中的BindingFlag.Instance选项。

关于核心问题,我很高兴地认为这是一个错误。 C#DLR绑定器无法进行逆向工程。 至少因为它的代码没有包含在参考源中,微软确实将其视为商业秘密。 它是。 您可以在connect.microsoft.com上提交