我有一个包含以下类的库:
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
,用TryInvokeMember
andTryGetMember
代替?它们具有相同的访问修饰符。
更新:在 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);
}
这是一个错误还是一个功能,由微软决定。但是,我希望将变量转换为动态不应限制访问。