当前位置:  开发笔记 > 编程语言 > 正文

从事件中返回一个值 - 这是一个好的做法吗?

如何解决《从事件中返回一个值-这是一个好的做法吗?》经验,为你挑选了6个好方法。

我正在做一个使用异步TCP套接字的小型多线程应用程序,但我会明白:我正在使用自定义事件从表单中读取值,并且事件使用的委托在完成时返回一个字符串.

我的问题是:这是正确的吗?可以从事件中返回值吗?或者有更好的方法吗?(比如使用表单的简单委托来读取值)



1> Dustin Campb..:

从事件中返回值通常很尴尬.实际上,我发现在一组传递给事件的自定义EventArgs中包含一个可写属性要容易得多,然后在事件触发后检查 - 类似于WinForms FormClosing事件的Cancel属性.


你能否详细说明`在一组自定义EventArgs中包含一个可写属性,并将其传递给event`部分?
@Odys使EventArgument对象自定义.创建结果生效的属性.

2> Thomas Leves..:

我不认为这是一个好主意......事件基本上是多播代理,因此可以有多个处理程序.在这种情况下你会得到哪个回报值?



3> Don Kirkby..:

我能想到的最接近的例子是WinForms中的FormClosing事件.它允许表单通过将eventArgs.Cancel属性设置为true来取消事件.为了让你做类似的事情,你可以定义你自己的事件args类,返回值作为该类的属性.然后每当你举起事件时传递一个事件args对象.提出事件的人可以检查事件args对象的返回值.接收事件的其他人也可以检查或更改事件args对象.

更新:我刚刚遇到AppDomain.AssemblyResolve事件,它似乎是一个返回值的事件.您似乎只需要声明一个返回值的委托类型,然后使用该委托类型定义您的事件.不过,我还没有尝试创建自己的事件.在事件参数上使用属性的一个优点是事件的所有订阅者都可以看到先前订阅者返回的内容.


注意:您可以使用任何委托来定义事件,因此最好定义一个事件,例如“公共事件Func <string,string,bool> SomeEvent;”,可以将其称为“ bool r = SomeEvent(“ foo” ,“ bar”);`

4> 小智..:

我知道这是在帖子后的年龄,但想到添加评论与代码解释达斯汀坎贝尔答案,如果有人遇到这个线程.我在试图决定什么是最佳实践时遇到了这个帖子,这就是答案的意思.

创建自己的自定义事件处理程序类

public class myCustomeEventArgs:EventArgs
{
    public bool DoOverride { get; set; }
    public string Variable1 { get; private set; }
    public string Variable2{ get; private set; }

    public myCustomeEventArgs(string variable1 , string variable2 )
    {
        DoOverride = false;
        Variable1 = variable1 ;
        Variables = variable2 ;
    }
}

因此,当您创建事件委托时,您可以使用您创建的事件args.

public delegate void myCustomeEventHandler(object sender, myCustomeEventArgs e);

在提升活动的课程中,您宣布活动.

public event myCustomeEventHandler myCustomeEvent;

因此,当您在类中触发事件时,侦听事件的类可以在事件集的正文中设置e.DoOverride = true; 因为它将在类中触发事件.

火灾事件例如:

if(myCustomeEvent != null)
{
    var eventArgs = new myCustomeEventArgs("Some Variable", "Another Varaible");
    myCustomeEvent(this, eventArgs);
    //Here you can now with the return of the event work with the event args
    if(eventArgs.DoOverride)
    {
       //Do Something
    }
}


事件在引发它们的同一个线程上运行.运行`myCustomeEvent(...)`的代码将控制(在同一个线程上运行)传递给所有订阅的事件处理程序.一旦所有代码都运行完毕,控件将在调用`myCusomeEvent(...)`后立即返回指令.如果没有订阅者,或者有订阅者将事件重新广播到另一个线程,那么`eventArgs`上的所有属性都将具有其默认值(对于字符串的`bool`和`null`为false).

5> 小智..:

注意:只有最后一个事件才会返回结果.

class Program
{
static event Func TheEvent;

    static void Main(string[] args)
    {
        TheEvent += new Func(Program_TheEvent);
        TheEvent +=new Func(Program_TheEvent2);
        TheEvent += new Func(Program_TheEvent3);
        var r = TheEvent("s"); //r == flase (Program_TheEvent3)
    }

    static bool Program_TheEvent(string arg)
    {
        return true;
    }

    static bool Program_TheEvent2(string arg)
    {
        return true;
    }

    static bool Program_TheEvent3(string arg)
    {
        return false;
    }        
}


谢谢!我想知道哪个事件处理程序会"赢".

6> Henk..:

我不知道这是不是最好的做法,但我是这样做的.

   Func IsDataValid;

   // some other code ....

   isValid = true;
   if (IsDataValid != null)
   {
      foreach (Func func in IsDataValid.GetInvocationList())
      {
         isValid &= func(Row);
      } 
   }

推荐阅读
乐韵答题
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有