动态在私有内部类上失败

Col*_*lin 4 c# dynamic inner-classes

当我运行以下代码时,我得到了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);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我切换thing到 avar它工作正常。如此明显,thingSetIt。当我使用动态时,为什么会失败?任何有效的东西不应该var在它有效时也有效吗dynamic

Thing<TInput>我认为这与成为私有内部类有关,因为当我将其公开时它会起作用。

Pet*_*iho 5

这是您的问题的一个更简单的示例:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

泛型和接口只是一种干扰。

问题是类型B(或者在您的情况下,Thing<IInput>)是私有类,因此在调用站点无法解析为实际类型。回想一下,这dynamic只是一个object变量,但编译已推迟到运行时。它的目的并不是让您在运行时做一些原本无法做的事情,并且“否则无法做”是根据调用站点的可访问类型来判断的(在本例中是这样的)情况下,是object)。

就运行时绑定器而言,类型很简单object(因此错误消息告诉您object不包含您想要的成员)。

当然,理论上可能可以dynamic以不同的方式实现,并且可以对有效类型进行更深入的搜索,它可以将对象视为将成员绑定到对象的目的(即实现的接口而不仅仅是对象的接口)。实际类型)。但这并不是它的实现方式,而且这样做的成本要高得多(无论是在原始设计和实现方面,当然还是在使用 的代码的运行时成本方面dynamic)。

相关阅读(可能重复):

这是动态的错误吗?
这是 C# 4 中动态绑定的漏洞吗?