【问题标题】:Uses of Action delegate in C# [closed]C# 中动作委托的使用 [关闭]
【发布时间】:2010-09-27 03:06:23
【问题描述】:

我正在与 C# 中的 Action Delegates 一起工作,希望能更多地了解它们并思考它们可能有用的地方。

是否有人使用过 Action Delegate,如果有,为什么?或者你能举一些可能有用的例子吗?

【问题讨论】:

    标签: c# lambda delegates action


    【解决方案1】:

    MSDN 说:

    此委托由 Array.ForEach 方法和 List.ForEach 方法来执行 对数组的每个元素的操作或 列表。

    除此之外,您可以将其用作通用委托,接受 1-3 个参数而不返回任何值。

    【讨论】:

    • 我从来没有注意到那些多参数版本的 Action。谢谢。
    【解决方案2】:

    我将它用作事件处理程序中的回调。当我引发事件时,我传入一个以字符串为参数的方法。这就是事件发起的样子:

    SpecialRequest(this,
        new BalieEventArgs 
        { 
                Message = "A Message", 
                Action = UpdateMethod, 
                Data = someDataObject 
        });
    

    方法:

       public void UpdateMethod(string SpecialCode){ }
    

    是事件Args的类声明:

    public class MyEventArgs : EventArgs
        {
            public string Message;
            public object Data;
            public Action<String> Action;
        }
    

    这样我可以调用从事件处理程序传递的方法,并带有一些参数来更新数据。我用它来向用户请求一些信息。

    【讨论】:

    • 嗨,Sorskoot,您能否扩展一下 UpdateMethod、MyEventArgs 和新的 BalieEventArgs 是如何一起玩的。传递给 UpdateMethod 的字符串 Message 是:UpdateMethod("A Message")?哪个方法使用对象“someDataObject”?提前致谢
    【解决方案3】:

    我曾经在一个项目中使用过这样的动作委托:

    private static Dictionary<Type, Action<Control>> controldefaults = new Dictionary<Type, Action<Control>>() { 
                {typeof(TextBox), c => ((TextBox)c).Clear()},
                {typeof(CheckBox), c => ((CheckBox)c).Checked = false},
                {typeof(ListBox), c => ((ListBox)c).Items.Clear()},
                {typeof(RadioButton), c => ((RadioButton)c).Checked = false},
                {typeof(GroupBox), c => ((GroupBox)c).Controls.ClearControls()},
                {typeof(Panel), c => ((Panel)c).Controls.ClearControls()}
        };
    

    它所做的只是针对一种控件存储一个操作(方法调用),以便您可以将表单上的所有控件清除回默认值。

    【讨论】:

    • 很好,变化不大,但有一个叫做 keyedbyTypeCollection 的东西,虽然我认为它可能是围绕字典(类型,对象)的。
    【解决方案4】:

    如果你有一个开关,你可以做的一件事:

    switch(SomeEnum)
    {
      case SomeEnum.One:
          DoThings(someUser);
          break;
      case SomeEnum.Two:
          DoSomethingElse(someUser);
          break;
    }
    

    借助动作的强大功能,您可以将该开关变成字典:

    Dictionary<SomeEnum, Action<User>> methodList = 
        new Dictionary<SomeEnum, Action<User>>()
    
    methodList.Add(SomeEnum.One, DoSomething);
    methodList.Add(SomeEnum.Two, DoSomethingElse); 
    

    ...

    methodList[SomeEnum](someUser);
    

    或者你可以更进一步:

    SomeOtherMethod(Action<User> someMethodToUse, User someUser)
    {
        someMethodToUse(someUser);
    }  
    

    ....

    var neededMethod = methodList[SomeEnum];
    SomeOtherMethod(neededMethod, someUser);
    

    仅举几个例子。当然,更明显的用途是 Linq 扩展方法。

    【讨论】:

    【解决方案5】:

    关于如何使用 Action 的示例。

    Console.WriteLine 有一个满足Action&lt;string&gt; 的签名。

        static void Main(string[] args)
        {
            string[] words = "This is as easy as it looks".Split(' ');
    
            // Passing WriteLine as the action
            Array.ForEach(words, Console.WriteLine);         
        }
    

    希望对你有帮助

    【讨论】:

      【解决方案6】:

      您可以对短事件处理程序使用操作:

      btnSubmit.Click += (sender, e) => MessageBox.Show("You clicked save!");
      

      【讨论】:

      • 您也可以将它们用于长的; btnSubmit.Click += (sender, e) => { MessageBox.Show("You clicked save!"); MessageBox.Show("你真的做到了!"); };
      【解决方案7】:

      这是一个小例子,展示了 Action 委托的用处

      using System;
      using System.Collections.Generic;
      
      class Program
      {
          static void Main()
          {
              Action<String> print = new Action<String>(Program.Print);
      
              List<String> names = new List<String> { "andrew", "nicole" };
      
              names.ForEach(print);
      
              Console.Read();
          }
      
          static void Print(String s)
          {
              Console.WriteLine(s);
          }
      }
      

      请注意,foreach 方法迭代名称集合并对集合的每个成员执行print 方法。随着我们朝着更实用的编程风格迈进,这对我们 C# 开发人员来说是一种范式转变。 (有关其背后的计算机科学的更多信息,请阅读:http://en.wikipedia.org/wiki/Map_(higher-order_function)

      现在,如果您使用的是 C# 3,您可以使用如下 lambda 表达式对其进行修改:

      using System;
      using System.Collections.Generic;
      
      class Program
      {
          static void Main()
          {
              List<String> names = new List<String> { "andrew", "nicole" };
      
              names.ForEach(s => Console.WriteLine(s));
      
              Console.Read();
          }
      }
      

      【讨论】:

        【解决方案8】:

        我在处理非法跨线程调用时使用它例如:

        DataRow dr = GetRow();
        this.Invoke(new Action(() => {
           txtFname.Text = dr["Fname"].ToString();
           txtLname.Text = dr["Lname"].ToString(); 
           txtMI.Text = dr["MI"].ToString();
           txtSSN.Text = dr["SSN"].ToString();
           txtSSN.ButtonsRight["OpenDialog"].Visible = true;
           txtSSN.ButtonsRight["ListSSN"].Visible = true;
           txtSSN.Focus();
        }));
        

        我必须感谢 Reed Copsey SO 用户 65358 的解决方案。我的完整问题是SO Question 2587930

        【讨论】:

          【解决方案9】:

          我们在测试中使用了很多 Action 委托功能。当我们需要构建一些默认对象并且稍后需要对其进行修改时。我做了一个小例子。要构建默认人 (John Doe) 对象,我们使用 BuildPerson() 函数。后来我们也添加了 Jane Doe,但我们修改了她的生日、姓名和身高。

          public class Program
          {
                  public static void Main(string[] args)
                  {
                      var person1 = BuildPerson();
          
                      Console.WriteLine(person1.Firstname);
                      Console.WriteLine(person1.Lastname);
                      Console.WriteLine(person1.BirthDate);
                      Console.WriteLine(person1.Height);
          
                      var person2 = BuildPerson(p =>
                      {
                          p.Firstname = "Jane";
                          p.BirthDate = DateTime.Today;
                          p.Height = 1.76;
                      });
          
                      Console.WriteLine(person2.Firstname);
                      Console.WriteLine(person2.Lastname);
                      Console.WriteLine(person2.BirthDate);
                      Console.WriteLine(person2.Height);
          
                      Console.Read();
                  }
          
                  public static Person BuildPerson(Action<Person> overrideAction = null)
                  {
                      var person = new Person()
                      {
                          Firstname = "John",
                          Lastname = "Doe",
                          BirthDate = new DateTime(2012, 2, 2)
                      };
          
                      if (overrideAction != null)
                          overrideAction(person);
          
                      return person;
                  }
              }
          
              public class Person
              {
                  public string Firstname { get; set; }
                  public string Lastname { get; set; }
                  public DateTime BirthDate { get; set; }
                  public double Height { get; set; }
              }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多