委托是一种引用类型,表示对具有特定参数列表和返回类型的方法的引用。 在实例化委托时,你可以将其实例与任何具有兼容签名和返回类型的方法相关联。 你可以通过委托实例调用方法。
委托用于将方法(该方法可以是静态方法,也可以是实例方法)作为参数传递给其他方法。 事件处理程序就是通过委托调用的方法。
using System;
using System.Collections.Generic;
using System.Linq;
namespace DemoProject_delegate01
{
class Program
{
public delegate string Reverse(string s); //创建特定签名的委托类型,在本例中即接受字符串参数并返回字符串参数的方法。
static string ReverseString(string s) //方法与定义的委托类型具有完全相同的签名,用于实现委托
{
return new string(s.Reverse().ToArray());
}
static void Main(string[] args)
{
Reverse s = ReverseString; //可将方法分配给相应委托类型的变量
Console.WriteLine(s("a string"));
///为简化开发过程,.NET 包含一组委托类型,程序员可重用这些类型而无需创建新类型。
///这些类型是 Func<>、Action<> 和 Predicate<>,可以使用它们而无需定义新的委托类型。
//Func<in T, out TResult> 通常用于现有转换的情况,也就是说需要将委托参数转换为其他结果时
Func<string, string> s2 = ReverseString;
Console.WriteLine(s2("string2"));
//“内联”委托,无需指定任何其他类型或方法
List<int> list = new List<int>();
for(int i =1; i<= 10; i++)
{
list.Add(i);
}
List<int> result = list.FindAll(
delegate(int no) //使用匿名方法来声明和初始化委托
{
return (no % 2 == 0);
}
);
foreach(var item in result)
{
Console.WriteLine(item); //2,4,6,8,10
}
List<int> result2 = list.FindAll(i => i % 2 == 0); //lambda 表达式只是指定委托的另一种方式
foreach (var item in result)
{
Console.WriteLine(item); //2,4,6,8,10
}
Console.ReadKey();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DemoProject_delegate01
{
class Demo03_delegate
{
//CLR 公共语言运行库 (common language runtime)环境中给我们内置了几个常用委托Action、 Action<T>、Func<T>、Predicate<T>
//一般我们要用到委托的时候,尽量不要自己再定义一 个委托了,就用系统内置的这几个已经能够满足大部分的需求,且让代码符合规范。
//总结:
//如果要委托的方法没有参数也没有返回值就想到Action
//有参数但没有返回值就想到Action<T>
//无参数有返回值、有参数且有返回值就想到Func<T>
//有bool类型的返回值,多用在比较器的方法,要委托这个方法就想到用Predicate<T>
//Action封装的方法没有参数也没有返回值,声明原型为:
//public delegate void Action();
public delegate void Action();
public void PrintDemo()
{
Console.WriteLine("this is a print method");
}
public void ActionDemo()
{
//Action a = PrintDemo;
Action a = new Action(PrintDemo);
a();
Action b = () => { Console.WriteLine("this is a print method"); };
b();
Action<int,int> c = ShowResult;
c(1, 2);
Action<int, int> d = (a, b) => { Console.WriteLine("a={0},b={1},a+b={2}", a, b, a + b); };
d(1, 2);
Func<int, int, bool> e = Compare;
var result1 = e(1, 2);
Console.WriteLine(result1);
Func<int,int,bool> f = (a, b) => { return a > b; };
var result2 = f(1, 2);
Console.WriteLine(result2);
Predicate<int> t = new Predicate<int>(Match); //定义一个比较委托
int[] arr = { 13, 45, 26, 98, 3, 56, 72, 24 };
int first = Array.Find(arr, t); //找到数组中大于60的第一个元素
Predicate<int> t2 = val => { return val > 60; };
int first2 = Array.Find(arr, t2);
}
//Action<T>是Action的泛型实现,也是没有返回值,但可以传入最多16个参数,两个参数的声明原型为:
//public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);
public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2); //in(泛型修饰符)
private void ShowResult(int a,int b)
{
Console.WriteLine("a={0},b={1},a+b={2}", a, b, a + b);
}
//Func<T>委托始终都会有返回值,返回值的类型是参数中最后一个,可以传入一个参数,也可以最多传入16个参数
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
public bool Compare(int a,int b)
{
return a > b;
}
//Predicate<T>委托表示定义一组条件并确定指定对象是否符合这些条件的方法,返回值始终为bool类型,声明原型为:
//public delegate bool Predicate<in T>(T obj); 不需要自己定义
public bool Match(int val)
{
return val > 60;
}
}
}