私人内部类动态失败
问题描述:
当我运行下面的代码时,我得到RuntimeBinderException: 'object' does not contain a definition for 'SetIt'
。私人内部类动态失败
public interface IInput { }
public interface IThing<in TInput>
{
void SetIt(TInput value);
}
public class ThingMaker
{
private class Thing<TInput> : IThing<TInput>
where TInput : IInput
{
public void SetIt(TInput value){}
}
private class Input : IInput {}
public IThing<IInput> GetThing()
{
return new Thing<IInput>();
}
public IInput GetInput()
{
return new Input();
}
}
class Program
{
static void Main(string[] args)
{
var thingMaker = new ThingMaker();
var input = thingMaker.GetInput();
dynamic thing= thingMaker.GetThing();
thing.SetIt(input);
}
}
如果我切换thing
到var
它工作正常。所以很清楚,thing
有SetIt
。当我使用动态时,这怎么会失败?当它是dynamic
时,不应该作为var
工作的任何东西也能工作吗?
我认为它与Thing<TInput>
是私人内部类有关,因为它在我公开时起作用。
答
这里是你的问题的一个简单的例子:
class A
{
class B
{
public void M() { }
}
public static object GetB() { return new B(); }
}
class Program
{
static void Main(string[] args)
{
dynamic o = A.GetB();
o.M();
}
}
仿制药和接口都只是分心。
问题是,类型B
(或在您的情况下,Thing<IInput>
)是一个私人类,所以在呼叫站点,无法解析为该实际类型。回想一下,dynamic
只是一个object
变量,但编译已经推迟到运行时。它不打算让你在运行时做一些你不能做的事情,并且“根本无法做到”是根据调用站点的可访问类型(在此情况,是object
)。
就运行时联编程序而言,类型仅仅是object
(因此错误消息告诉您object
不包含您想要的成员)。
当然,理论上dynamic
可能已经以不同的方式实现了,并且可以更深入地搜索它可以处理对象的有效类型,以便将成员绑定到对象(即实现的接口而不仅仅是对象的实际类型)。但这并不是如何实现的,而且这样做会更加昂贵(无论是在原始设计和实现方面,还是在使用dynamic
的代码的运行时代码方面)。
相关读数(可以说是一式两份):
Is this a bug in dynamic?
Is this a hole in dynamic binding in C# 4?