代码之家  ›  专栏  ›  技术社区  ›  Biswanath

C[关闭]中动作委托的使用

  •  132
  • Biswanath  · 技术社区  · 17 年前

    我正在与C的行动代表合作,希望能更多地了解他们,并思考他们在哪里可能有用。

    有人使用过行动代表吗?如果有,为什么?或者你能举一些例子说明它在哪里可能有用吗?

    9 回复  |  直到 17 年前
        1
  •  25
  •   arul    17 年前

    MSDN表示:

    此委托由 array.foreach方法和 list.foreach方法执行 对数组的每个元素执行的操作,或 名单。

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

        2
  •  114
  •   Manos Dilaverakis    14 年前

    下面是一个小例子,展示了操作委托的有用性

    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();
        }
    }
    
        3
  •  67
  •   Richard Marskell - Drackir Sunil Tandon    14 年前

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

    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扩展方法。

        4
  •  16
  •   Aaron Powell    17 年前

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

    btnSubmit.Click += (sender, e) => MessageBox.Show("You clicked save!");
    
        5
  •  14
  •   Nathan W    17 年前

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

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

    它所做的就是存储一个针对控件类型的操作(方法调用),这样您就可以将窗体上的所有控件清除回默认值。

        6
  •  13
  •   Binary Worrier    17 年前

    例如如何使用action<gt;。

    console.writeline的签名令人满意 Action<string> .

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

    希望这有帮助

        7
  •  11
  •   Community Mohan Dere    9 年前

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

    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

        8
  •  3
  •   Sorskoot    17 年前

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

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

    方法:

       public void UpdateMethod(string SpecialCode){ }
    

    是事件参数的类声明:

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

    通过这种方式,我可以使用某个参数调用从事件处理程序传递的方法来更新数据。我用这个向用户请求一些信息。

        9
  •  1
  •   evilone    11 年前

    我们在测试中使用了很多动作委托功能。当我们需要构建一些默认对象时,稍后需要修改它。我举了个小例子。要构建默认的Person(John Doe)对象,我们使用 BuildPerson() 功能。后来我们也加上了JaneDoe,但我们修改了她的出生日期、名字和身高。

    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; }
        }