1 委托
1.1 委托简介
委托是C#语言中的一种高级语法,其作为一种与类同级的对象,定义在命名空间内。
//委托的定义
namespace TestNameSpace
{
public delegate void testDelegate (string text);
public class TestClass
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
委托是一个对象,它知道该如何调用方法,作为一个引用类型,和类是同级的,委托实例 把方法赋值给委托变量时调用者调用委托,委托调用目标方法。
1.2 委托是一种方法模板
和面向对象中的类的概念相似,我们都知道类作为一个对象的模板,各种对象都可以被描述为一个类或者继承于某个类的子类。
而委托也是一种模板,它是函数/方法的模板,如上面所看到的委托 testDelegate ,其就是一类方法的模板,其代表的是输入类型为 string ,返回类型为 void 的一类函数。其实例化的过程需要接收该类型的函数。如下方示例所示:
using System;
namespace TestNameSpace
{
public delegate void testDelegate(string text);
public class TestClass
{
static void Main(string[] args)
{
MethodClass methodClass = new MethodClass();//实例化类 用于引用类中存在的方法
testDelegate testDelegate_1 = new testDelegate( methodClass.TestMethod_1);//实例化委托 方法作为委托的参数
testDelegate testDelegate_2 = new testDelegate( methodClass.TestMethod_2);//实例化委托 方法作为委托的参数
testDelegate_1(" 成功");
testDelegate_2(" 成功");
}
}
public class MethodClass
{
public void TestMethod_1(string s)
{
Console.WriteLine("这是第一个方法" + s);
}
public void TestMethod_2(string s)
{
Console.WriteLine("这是第二个方法" + s);
}
}
}
输出结果为
这是第一个方法 成功
这是第二个方法 成功
可以看到委托与类同级,委托也需要进行实例化以获得对象,委托实例化时需要的参数是与其定义相同的方法。
若想执行目标方法,可以直接借用委托并且输入方法参数,来获取目标输出。
2 Action 委托
命名空间: System
程序集: System.Runtime.dll
Action 委托是 .NET Framwork 自带的委托,在使用 Action 委托时,可以省去自定义显式委托的步骤,简化代码。
需要注意的是 :Action()委托 所接受的方法 可以一个或者多个参数,但是不能有返回值
2.1 重载1 Action()
封装一个方法,该方法不具有参数,且不具有返回值。
public delegate void Action();//这是一个官方定义的委托 是一个确定的委托名称 其参数是一个没有参数 没有返回值的方法
使用 Action作为委托,就不必再显示定义委托,下述示例,就定义了 showvalue()委托,最后使用 showvalue()委托实现了对应的方法,但是也可以直接用 Action()委托,因为它在程序集中已经被定义了,不需要再次定义。
using System;
using System.Windows.Forms;
public delegate void ShowValue(); //这里指的就是显式定义委托 ShowValue()
public class Name
{
private string instanceName;
public Name(string name)
{
this.instanceName = name;
}
public void DisplayToConsole()
{
Console.WriteLine(this.instanceName);
}
public void DisplayToWindow()
{
MessageBox.Show(this.instanceName);
}
}
public class testTestDelegate
{
public static void Main()
{
Name testName = new Name("Koani");
ShowValue showMethod = testName.DisplayToWindow;
//如果使用Action委托 那么就不用显式定义 showValue 委托
//Action showMethod = testName.DisplayToWindow;
//Action showMethod = () => testName.DisplayToWindow();//还可以使用 lamba 表达式
showMethod();
}
}
2.2 重载2 Action< T >
封装一个方法 该方法只有一个参数,且没有返回值
public delegate void Action<in T>(T obj);
T 代表委托封装的方法的参数类型,属于逆变类型参数 ,想要了解泛型逆变和协变类型参数可以参阅泛型中的协变和逆变 | Microsoft Learn
参数 T obj
此委托 Action < T >封装的方法所需的参数 obj;意思就是说,这个obj 是 委托所需方法所需的参数。
示例
以下示例演示如何使用 Action 委托来打印对象的内容 List 。 在此示例中, Print 该方法用于向控制台显示列表的内容。 此外,C# 示例还演示了使用匿名方法向控制台显示内容。 请注意,该示例不显式声明变量 Action 。 相反,它会将引用传递给采用单个参数的方法,并且不向 List.ForEach 该方法返回值,该方法的单个参数是 Action 委托。 同样,在 C# 示例中,Action不会显式实例化委托,因为匿名方法的签名与该方法预期的List.ForEach委托的Action签名匹配。
List<string> names = new List<string>();//新建泛型列表
names.Add("Bruce");
names.Add("Alfred");
names.Add("Tim");
names.Add("Richard");
// 加入4个列表元素
// Display the contents of the list using the Print method.
names.ForEach(Print);
//Lsit<T>.ForEach 函数 对List<T>中的每个元素执行指定的操作
public void ForEach (Action<T> action); //接受 Action <T> 委托类型参数 对每个元素执行 委托中的方法
// The following demonstrates the anonymous method feature of C#
// to display the contents of the list to the console.
names.ForEach(delegate(string name)
{
Console.WriteLine(name);
});
void Print(string s)
{
Console.WriteLine(s);
}
/* This code will produce output similar to the following:
* Bruce
* Alfred
* Tim
* Richard
* Bruce
* Alfred
* Tim
* Richard
*/
2.3 重载 3 Action<T,T,T>
代码示例
using System;
namespace VSCodeProject
{
class Program
{
static void Main(string[] args)
{
Test test = new Test("test");
Action<string> action = test.Method; action(test.s);
Action action2 = test.Method2; action2();//委托是一种特殊的方法
Action<string ,string ,string> action3 = test.Method3; action3("a","b","c");
}
}
public class Test
{
public string s;
public Test(string S)
{
s = S;
}
public void Method(string s)
{
Console.WriteLine(s + " 这是有一个参数的委托方法");
}
public void Method2()
{
Console.WriteLine("这是无参数的委托方法");
}
public void Method3(string s1,string s2,string s3)
{
Console.WriteLine(s1 + s2 + s3 + " 这是有三个参数的委托方法");
}
}
}
输出结果
test 这是有一个参数的委托方法
这是无参数的委托方法
abc 这是有三个参数的委托方法