C # 中 Action 委托的使用

我和 C # 中的行动代表们一起工作,希望能够更多地了解他们,并思考他们在哪些方面可能有用。

有人使用过行动代表吗? 如果有,原因是什么?或者你可以给出一些例子,在哪里它可能是有用的?

123028 次浏览

MSDN 表示:

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

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

我将其用作事件处理程序中的回调。当我引发事件时,我传入一个带有字符串参数的方法。这就是事件的发生:

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

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

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

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

它所做的只是存储针对某种控件类型的操作(方法调用) ,以便可以将窗体上的所有控件清除回默认值。

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

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

有关如何使用 Action < > 的示例。

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

希望这个能帮上忙

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

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

下面是一个显示 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();
}
}

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

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

我必须相信里德科普塞 SO 用户65358的解决方案。我的全部问题与答案是 问题2587930

我们在测试中使用了许多 Action 委托功能。当我们需要构建一些默认对象并在以后需要修改它时。我没有杀鸡儆猴。要构建缺省的 person (JohnDoe)对象,我们使用 BuildPerson()函数。后来我们也添加了无名氏,但是我们修改了她的出生日期、名字和身高。

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