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

Posted

技术标签:

【中文标题】将动态方法调用移动到类库会导致 C# 中的 RuntimeBinderException【英文标题】:Moving dynamic method call to class library causes a RuntimeBinderException in C# 【发布时间】:2014-10-15 21:17:06 【问题描述】:

我正在阅读interesting article using of DataFlow + dynamic method invocation to make an Actor model in C#。这是完整的示例。

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();
        
    

这按预期工作。将 Actor 和 Message 类移动到新的类库中并正确引用会导致问题。运行时,它会在 Actor 构造函数中的动态 self.Handle(mess); 上抛出 RuntimeBinderException,即 Actors.Actor does not contain a definition for 'Handle'。是否存在我在 MSDN 中似乎找不到的动态方法调用的限制,或者我缺少从单独的类库中执行此操作的语法魔术?

【问题讨论】:

【参考方案1】:

原作者回复了我。

嗨,

问题是你已经在里面声明了你的消息和演员 内部 NotWorkingProgram 类。

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

当您运行程序时,运行时会尝试查找名为 带有典型“存款”参数的“句柄”。它什么都找不到 因为 AccountActor 类在 Actors 项目中不可见。 它隐藏在不可见的 NotWorkingProgram 中。如果你使 NotWorkingProgram 类 public(或移动 Deposit 和 AccountActor 外面的课程)它有效!

问候约翰

我把它留在这里是因为 RuntimeBinderException 没有提供太多信息,更不用说任何暗示类/方法隐私是可能的根

【讨论】:

以上是关于将动态方法调用移动到类库会导致 C# 中的 RuntimeBinderException的主要内容,如果未能解决你的问题,请参考以下文章

将脚手架项目添加到类库

C# 从类库中获取资源图片,把图片资源保存到类库中

在托管 C++ 类库中使用 System::Drawing 命名空间

将静态库链接到类库项目

动态地将模块中的方法添加到类的特定实例

将 MUI 组件添加到组件库会导致错误“只能在功能组件的主体内部调用挂钩”