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

时间:2014-08-22 05:05:17

标签: c# dynamic actor dataflow tpl-dataflow

我正在读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();
        }
    }
}

这是按预期工作的。移动演员&amp;将消息类放入新的类库并正确引用导致问题。运行时,它会在Actor构造函数中的动态self.Handle(mess);上抛出一个RuntimeBinderException,说Actors.Actor does not contain a definition for 'Handle'。动态方法调用是否有限制,我似乎无法在MSDN或语法魔法中找到我从单独的类库中执行此操作?

1 个答案:

答案 0 :(得分:1)

原作者回复了我。

  

您好,

     

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

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

运行程序时,运行时会尝试查找名为的方法   &#39;处理&#39;参数为typ&#39; Deposit&#39;。它无法找到任何东西   因为从Actors项目中看不到AccountActor类。   它隐藏在不可见的NotWorkingProgram中。如果你做了   NotWorkingProgram类public(或移动Deposit和AccountActor   外面的课程)它的工作原理!

     

问候约翰

我离开这里导致RuntimeBinderException没有提供太多信息,更不用说任何类/方法隐私是可能的根