简体   繁体   English

将动态方法调用移至类库会导致C#中的RuntimeBinderException

[英]Moving dynamic method call to class library causes a RuntimeBinderException in C#

I was reading an interesting article using of DataFlow + dynamic method invocation to make an Actor model in C# . 我正在阅读一篇有趣的文章,文章使用DataFlow +动态方法调用在C#中创建Actor模型 Here is the completed example verbatim. 这是逐字记录的完整示例。

using System;
using System.Threading.Tasks.Dataflow;

namespace ConsoleApplication
{
    public abstract class Message { }

    public abstract class Actor
    {
        private readonly ActionBlock<Message> _action;

        public Actor()
        {
            _action = new ActionBlock<Message>(message =>
            {
                dynamic self = this;
                dynamic mess = message;
                self.Handle(mess);
            });
        }

        public void Send(Message message)
        {
            _action.Post(message);
        }
    }

    class Program
    {
        public class Deposit : Message
        {
            public decimal Amount { get; set; }
        }

        public class QueryBalance : Message
        {
            public Actor Receiver { get; set; }
        }

        public class Balance : Message
        {
            public decimal Amount { get; set; }
        }

        public class AccountActor : Actor
        {
            private decimal _balance;

            public void Handle(Deposit message)
            {
                _balance += message.Amount;
            }

            public void Handle(QueryBalance message)
            {
                message.Receiver.Send(new Balance { Amount = _balance });
            }
        }

        public class OutputActor : Actor
        {
            public void Handle(Balance message)
            {
                Console.WriteLine("Balance is {0}", message.Amount);
            }
        }

        static void Main(string[] args)
        {
            var account = new AccountActor();
            var output = new OutputActor();

            account.Send(new Deposit { Amount = 50 });
            account.Send(new QueryBalance { Receiver = output });

            Console.WriteLine("Done!");
            Console.ReadLine();
        }
    }
}

This works as intended. 这按预期工作。 Moving Actor & Message classes into a new class library and referencing properly causing an issue. 将Actor&Message类移动到新的类库中并正确引用会导致问题。 When run it throws a RuntimeBinderException on the dynamic self.Handle(mess); 运行时,它会在动态self.Handle(mess);上引发RuntimeBinderException self.Handle(mess); within the Actor constructor saying Actors.Actor does not contain a definition for 'Handle' . 在Actor构造函数中说Actors.Actor does not contain a definition for 'Handle' Are there limitations to dynamic method calls I can't seem to find in the MSDN or syntax magic I missing to do this from a separate class library? 我似乎无法在MSDN中找到的动态方法调用有局限性,或者缺少从单独的类库执行此操作的语法魔术?

The original author got back to me. 原始作者回到我身边。

Hi, 嗨,

The problem is that you have declared your messages and actors inside the internal NotWorkingProgram class. 问题是您已经在内部NotWorkingProgram类中声明了消息和参与者。

class NotWorkingProgram  // no access modifier! Default is 'internal' {
    public class Deposit : Message
    ...
    public class AccountActor : Actor
    {
        public void Handle(Deposit message)
        ...
    } } 

When you run the program the runtime tries to find a method named 'Handle' with a parameter of typ 'Deposit'. 当您运行该程序时,运行时将尝试找到一个参数为'Deposit'的名为'Handle'的方法。 It can't find anything because the AccountActor class is not visible from the Actors Project. 它找不到任何内容,因为从Actors项目中看不到AccountActor类。 It is hidden inside the invisible NotWorkingProgram. 它隐藏在不可见的NotWorkingProgram内部。 If you make the NotWorkingProgram class public (or move the Deposit and AccountActor classes outside) it works! 如果将NotWorkingProgram类公开(或将Deposit和AccountActor类移到外部),它将起作用!

Regards Johan 问候约翰

I'm leaving this here cause the RuntimeBinderException doesn't give much info, let alone any hint of class/method privacy being a possible root 我将其留在此处是因为RuntimeBinderException并没有提供太多信息,更不用说任何类/方法隐私提示可能是根

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

相关问题 C#动态-“ RuntimeBinderException” - C# Dynamic - “RuntimeBinderException” 在C#4.0中使用动态的RuntimeBinderException - RuntimeBinderException with dynamic in C# 4.0 尝试在动态创建的程序集上绑定动态方法会导致RuntimeBinderException - Attempting to bind a dynamic method on a dynamically-created assembly causes a RuntimeBinderException RuntimeBinderException - C#.NET 4动态关键字 - 帮助我理解为什么方法不匹配 - RuntimeBinderException - C# .NET 4 Dynamic Keyword - Help Me Understand Why Method Isn't Matching 将C#动态与COM对象一起使用会引发RuntimeBinderException,以记录已实现接口的方法 - Using C# dynamic with COM object throws RuntimeBinderException for documented method of implemented interface 在加载 class 库时调用一次 c# 方法 - Call a c# method once on load of a class library 在C#中调用动态PSObject属性将返回RuntimeBinderException - Calling dynamic PSObject Properties in C# returns RuntimeBinderException 拦截动态调用以避免RuntimeBinderException - Intercept a dynamic call to avoid RuntimeBinderException 在Visual C#中从另一个类调用动态方法 - Call dynamic method from another class in visual c# 在C#中调用动态方法 - Call dynamic method in c#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM