举一个很简单的例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication3
{
public delegate T OurDelegate<T>(T obj); //定义了一个泛型委托
class MyClass
{
public int Func1(int argument)
{
Console.WriteLine("Func1: i={0}", argument);
return argument;
}
public int Func2(int argument)
{
argument *= 2;
Console.WriteLine("Func2: i={0}", argument);
return argument;
}
public int Func3(int argument)
{
argument *= 4;
Console.WriteLine("Func3: i={0}", argument);
return argument;
}
public static void Hello()
{
Console.WriteLine("Hello");
}
public static void Welcome()
{
Console.WriteLine("Welcome");
}
}
class Program
{
static void Main(string[] args)
{
MyClass myclass=new MyClass();
OurDelegate<int> del1 = myclass.Func1;
del1(3);
}
}
}
为了开发方便,.NET基类库提供了几个预定义好的委托:
Func系列委托:
public delegate TResult Func<TResult>();
public delegate TResult Func<T,TResult>(T arg);
public delegate TResult Func<T1,T2, TResult>(T1 arg1,T2 arg2);
public delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
public delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3,T4 arg4);
所有这些看上去复杂的声明中,TResult是委托所接收方法的返回值类型,前面的Tn是(如果有的话)就是委托所接收方法的形参类型。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
int[] array = new int[10] { 1,1,2,3,4,5,6,7,8,9};
Console.WriteLine(Calit(Add, array, 0, 9));//将方法作为参数
Console.WriteLine(Calit(Multiply,array,0,9));
}
static int Calit(Func<int,int,int> op,int[] array,int from,int to)//将方法作为参数:func<int,int,int> 类型的op
{
int result=array[from];
for (int i = from+1; i <= to; i++)
{
result = op(result,array[i]);//在这个例子中被用为累加或累积
}
return result;
}
public static int Add(int x,int y)
{
return x + y;
}
public static int Multiply(int x,int y)
{
return x * y;
}
}
}
Action系列的委托:
这一类的委托时没有返回值的,他也有好多种重载形式:
public delegate void Func();
public delegate void Func<T>(T arg);
public delegate void Func<T1, T2>(T1 arg1, T2 arg2);
public delegate void Func<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3);
public delegate void Func<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
Predicate类型的委托:
public delegate bool Predicate<T>(T obj);
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication3
{
class MyClass
{
public int value;
public string flag;
}
class Program
{
static List<MyClass> GetMyClass()//错误的添加方式
{
List<MyClass> mine = new List<MyClass>();
MyClass obj = new MyClass();
for (int i = 0; i < 10; i++)
{
obj.value = i;
obj.flag = "hello" + i.ToString();
mine.Add(obj);
}
return mine;
}
private static List<MyClass> GetMyClassList()//正确的添加方式
{
List<MyClass> yours = new List<MyClass>();
MyClass obj2 = null;
Random rnd = new Random();
for (int i = 0; i < 10; i++)
{
obj2 = new MyClass { value = rnd.Next(10, 100), flag = "welcome" + i.ToString() };
yours.Add(obj2);
}
return yours;
}
private static void ShowList(List<MyClass> lst)
{
if (lst == null)
{
return;
}
//foreach (MyClass item in lst)
//{
// Console.WriteLine("{0} {1}",item.value,item.flag);
//}
for (int i = 0; i < 10; i++)
{
Console.Write(lst[i].value);
Console.WriteLine(lst[i].flag);
}
}
private static bool GetValueMorethan50(MyClass mine)//Predicate委托对应的方法
{
if (mine.value > 50)
{
return true;
}
return false;
}
static void Main(string[] args)
{
//GetMyClass();
List<MyClass> myclassData = null;
myclassData = GetMyClassList();
ShowList(myclassData);
Predicate<MyClass> pred = GetValueMorethan50;//建立Predicate委托
List<MyClass> element = myclassData.FindAll(pred);//方法为参数(委托),找所有符合项
if (element == null)
{
Console.WriteLine("未找见");
}
Console.WriteLine("找到了:");
foreach (MyClass item in element)
{
Console.WriteLine("{0}{1}", item.value,item.flag);
}
}
}
}
值得注意的一点是,使用Predicate<T>委托时,其判断条件一般是“外部硬性规定的”,而并不是自身规定。否则(比如要检查其中最大的元素)就并不适合用这个委托变量。