I have a library with the following classes:
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); } }
and the program that uses them:
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); }
Output signal
inside Foo getter entity.Foo = foo inside TryInvokeMember(binder.Name = 'Bar') inside TryGetMember(binder.Name = 'Bar')
and then I get an exception
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: `EntityLib.Entity.Bar(int)' is inaccessible due to its protection level
Why does a dynamic object directly refer to the Foo property, but does not call the Bar method and uses TryInvokeMember and TryGetMember ? They have the same access modifiers.
Update: The described behavior is observed in Mono. Microsoft does not work already when accessing the Foo property. The following code works as intended:
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); }
Whether this will be a bug or any function should be decided by Microsoft. However, I expect the conversion of the variable to dynamic should not restrict access.