简体   繁体   English

C#Late Binding和dynamic关键字不能一起使用

[英]C# Late Binding and dynamic keyword won't work together

I'm trying to follow the examples on the book Pro C# 5.0, and I've stumbled upon one that I cannot make work: 我试图按照Pro C#5.0这本书中的例子,我偶然发现了一个我无法工作的例子:

static void Main() {

    Assembly asm = Assembly.Load("CarLibrary");

    Type MiniVan = asm.GetType("CarLibrary.MiniVan");

    dynamic d = Activator.CreateInstance(Minivan);

    Console.WriteLine("Type of d is {0}", d.GetType()); // Type is CarLibrary.MiniVan

    MethodInfo m = MiniVan.GetMethod("TurboBoost");
    m.Invoke(d, null); // This works fine, and prints out "Turbo Boosting"

    d.TurboBoost(); // This doesn't work like the book says it should. 
                    // I get: object does not contain a definition for TurboBoost;

Here's the declaration of CarLibrary: 这是CarLibrary的宣言:

namespace CarLibrary {

    // UPDATE: I just realized that I had declared MiniVan internal
    internal MiniVan {

        public void TurboBoost() {

            Console.WriteLine("Turbo Boosting");
        }
    }
}

So, even though MiniVan is declared as INTERNAL, using Reflection I can still create an instance of MiniVan, and make a call to TurboBoost(). 因此,即使MiniVan被声明为INTERNAL,使用Reflection我仍然可以创建一个MiniVan实例,并调用TurboBoost()。 But if I use the dynamic keyword, a call to TurboBoost() doesn't work. 但是如果我使用dynamic关键字,则调用TurboBoost()不起作用。 If MiniVan is declared PUBLIC though, both cases work perfectly. 如果MiniVan被声明为PUBLIC,两种情况都可以完美地运行。

Could someone tell me if all that is as it's suppose to be? 有人可以告诉我,如果这是假设的那样吗?

dynamic respects the accessibility rules, which includes not just the member's accessibility, but also whether the object's type is internal , private (nested), etc. dynamic is not just a wrapper around reflection - it is more: would this have worked in regular C# from here . dynamic尊重可访问性规则,其中不仅包括成员的可访问性,还包括对象的类型是internalprivate (嵌套的)等等。 dynamic 不仅仅是反射的包装 - 它更多: 这是否适用于常规C#从这里开始

Which means that the same use of dynamic executed inside the CarLibrary assembly , would have worked. 这意味着CarLibrary程序集内执行相同的dynamic使用会起作用。 If you want to access type-members via dynamic , then it must be public , or at a minimum: accessible in the calling context. 如果您想通过dynamic访问类型成员,那么它必须是public ,或者至少是:在调用上下文中可访问。

In particular, this prevents you from cheating the runtime by accessing public members of internal types that you were never supposed to know about directly . 特别是,这可以防止您通过访问您从未应该直接了解internal类型的public成员来欺骗运行时。 For example, suppose a core CLI type implements some interface: 例如,假设核心CLI类型实现了一些接口:

public ISomeInterface {...}
internal SomeMicrosoftType : ISomeInterface
{
    public void FireTheMissiles() {...}
}

Now; 现在; there may well be an API that exposes that object as an ISomeInterface instance - so we could legitimately have a reference to an object of that. 可能有一个API将该对象公开ISomeInterface实例 - 因此我们可以合法地引用该对象。 In our regular code, we could have accessed members of ISomeInterface , but we would not have been able to call FireTheMissiles . 在我们的常规代码中,我们可以访问ISomeInterface成员,但我们无法调用FireTheMissiles However, if what you are suggesting worked , then we could do: 但是,如果您的建议有效 ,那么我们可以这样做:

ISomeInterface innocent = ...
dynamic evil = innocent;
evil.FireTheMissiles();

Now, yes we can do that via reflection , but reflection has additional checks, especially if we aren't running with full trust. 现在, 是的,我们可以通过反射来做到这一点,但反射有额外的检查,特别是如果我们没有完全信任运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM