Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从接受参数的事件调用无参数操作_C#_Delegates_Closures - Fatal编程技术网

C# 从接受参数的事件调用无参数操作

C# 从接受参数的事件调用无参数操作,c#,delegates,closures,C#,Delegates,Closures,我正在尝试编写一个方便的方法,旨在帮助将泛型委托绑定到类事件 其中的关键部分是,类上的事件接受1个或多个参数,例如object和各种参数,我希望包装的操作接受0个参数 一个简单的例子是: public class Test { //Other class. <int,bool> is just an example, it could be anything public event Action<int, bool> MyEvent; //H

我正在尝试编写一个方便的方法,旨在帮助将泛型委托绑定到类事件

其中的关键部分是,类上的事件接受1个或多个参数,例如object和各种参数,我希望包装的操作接受0个参数

一个简单的例子是:

public class Test
{
    //Other class.  <int,bool> is just an example, it could be anything
    public event Action<int, bool> MyEvent;

    //Helper
    public void AddAction(Action a, object cls, string eventName)
    {
        var evt = cls.GetType().GetEvent(eventName);

        //Need some code in here to wrap the action
        evt.AddEventHandler(cls, a);
    }
}
显然,当我们试图运行上面的代码时,它可能会抛出异常

编辑:我应该详细说明一下。我知道我可以做a,b=>a,但在这种情况下,我不知道事件的类型

我希望能够生成一个新的委托,它接受int和bool,然后在内部调用该操作

我曾尝试编写一个DynamicMethod/ILGenerator,但运气不好,因此我正在寻找如何实现这一点的输入和建议。据我所知,IL生成是唯一的方法

提前感谢。

我必须重命名您的var eventline代码:它不会编译,因为event是一个关键字,与您之前使用的一样,而不是在表达式中。您说过我希望能够生成一个新的委托,它接受int和bool,然后在内部调用该操作

下面是我将如何使用匿名代理来完成它。我正在编辑我以前的帖子来纠正一个错误

假设您的MyEvent将与某些事件处理代码连接,如:

 public void HookUpTheEventWithTheHandler()
    {
        MyEvent += MyEventHandler;

    }

    public void MyEventHandler(int x, bool condition)
    {
        // Do some processing here....
    }
因此,我假设下一步它不会为空:

我的AddAction方法可能如下所示:

    public void AddAction(Action<int,bool> a, object cls, string eventName)
    {
        var eventVar = cls.GetType().GetEvent(eventName);
          a += delegate(int x, bool condition)
        {
            MyEvent(x, condition);
        };

          eventVar.AddEventHandler(cls, a);

    }
现在,如果您事先不知道类型,那么您可能需要使用genericity

我会这样做的

public class Test<I, B> {
    ....
     public event Action<I, B> MyEvent2;

      public void AddAction2(Action<I, B> a, object cls, string eventName)
      {
          var eventVar = cls.GetType().GetEvent(eventName);
          a += delegate(I x, B condition)
          {
              MyEvent2(x, condition);
          };

          eventVar.AddEventHandler(cls, a);

      }

我花了很多时间来解决这个问题,最后又回到了Linq表达式

我花了一段时间才意识到DynamicMethod的主要问题是它没有范围。当它被构建时,可以将其视为一组静态指令,因此,除非将其作为参数传递,否则它不知道“this”是什么

我最后要做的是编译一个带有预期参数的表达式,并调用委托上的预期方法

下面是一些示例代码:

public static class AnonymousAction
{
    public static Delegate WrapDelegate(Action action, Type targetType)
    {
        var invoke = targetType.GetMethod ("Invoke");
        if (invoke == null)
            throw new ArgumentException ("ofType must be delegate");

        var parameters = invoke.GetParameters ();
        var expressionParams = new ParameterExpression[parameters.Length];
        for (int i=0; i<parameters.Length; ++i)
        {
            expressionParams [i] = Expression.Parameter (parameters [i].ParameterType);
        }

        var call = Expression.Call (
            Expression.Constant(action),
            typeof(Action).GetMethod ("Invoke")
            );

        return Expression.Lambda (targetType, call, expressionParams).Compile ();
    }
}

public class MyReceiver
{
    public event Action<MyReceiver, int> OnAction;

    public void Do()
    {
        OnAction (this, 22);
    }
}

public class Test
{
    public void Run()
    {
        Action onAction = () => {
            Console.WriteLine ("Did something");
        };

        var receiver = new MyReceiver ();
        var evt = receiver.GetType ().GetEvent ("OnAction");
        evt.AddEventHandler (receiver, AnonymousAction.WrapDelegate (onAction, evt.EventHandlerType));

        receiver.Do ();
    }
}
static void Main()
{
    var t = new Test ();
    t.Run ();
}

您能对这一行进行简单的编辑吗:var event=cls.GetType.geteventname;因为事件是一个关键词谢谢。但事情是这样的。我不知道参数是int,bool。我把它作为这个案例的一个例子,它们可以是任何东西。我将编辑我的问题来演示这一点。只要你告诉编译器你正在使用泛型类型,你的参数可以是任何东西。我编辑了我的contrib来说明这一点,我甚至不知道参数的数量,只是通过GetEvent知道它的类型。