C#中委托(delegate、Func、Action、precidate)学习笔记
什么是委托
委托通过delegate关键字来标记。委托是一个类,所以他的实例化跟类的实例化一样。通过使用Delegate类,委托实例可以封装属于可调用实体的方法。
通过委托可以间接地调用一个方法。委托包含对方法的引用,使用委托可以在运行时动态的设定要调用的方法,执行或调用一个委托将执行该委托引用的方法。
委托具有以下特点:
- 委托类似于C/C++的函数指针,但它是类型安全的。
- 委托允许将方法作为参数进行传递
- 委托可以用于定义回调方法。
- 委托可以将多个方法关联起来。
- 委托所指向的方法不需要与委托签名精确匹配(涉及委托中的协变和逆变,暂时还不理解)。
定义和使用委托
定义和使用委托三个步骤,声明委托类型、实例化委托对象、调用委托方法。
-
声明委托类型
[修饰符] delegate 返回类型 委托类型名(参数列表)private delegate void mydelegate(int n);
-
实例化委托对象
声明了委托类型后,必须创建一个它的实例,即创建委托对象并使之与特定的方法关联。
语法格式:
委托类型名 委托对象名 = new 委托类型名(静态方法或实例方法);class MyClass { public void fun1(int n) { //...... } } MyClass obj = new MyClass(); mydelegate p = new mydelegate(obj.fun1);
其中fun1方法中有一个int形参,其返回类型为void,它必须与mydelegate类型的声明相一致。
-
调用委托方法
语法格式:委托对象名(实参列表);p(100);
delegate
声明委托就必须使用关键字“delegate”,委托是先声明,后实例化。至少0个参数,至多32个参数。
简单使用
private delegate void Say();
private static void SayHello()
{
Console.WriteLine("Hello");
}
static void Main(string[] args)
{
Say sayhello = SayHello;//实例化委托对象
sayhello();//调用委托
}
结合匿名方法使用
delegate void mydelegate(string mystr);
class Program
{
static void Main(string[] args)
{
mydelegate p = delegate(string mystr)
{
Console.WriteLine(mystr);
};
p("String");
}
}
结合Lambda表达式使用
delegate void mydelegate(string mystr);
class Program
{
static void Main(string[] args)
{
mydelegate p = mystr => Console.WriteLine(mystr);
p("Sting");
}
}
Func
Func是有返回值的泛型委托,可以接受0个至16个传入参数。在声明Func时,至少有一个参数作为返回值。规定是将最后一个参数作为返回值。
Func<TResult> func = LoadingResources;
Func<T, T, TResult> func = Cacl;
Func<T1, T2, TResult> func = Cacl;
......
简单使用
public static int Cacl(int a, int b)
{
return a * b;
}
static void Main(string[] args)
{
Func<int, int, int> cacl = Cacl;
int c = cacl(2, 3);
}
结合匿名方法使用
static void Main(string[] args)
{
Func<int, int, int> calc = delegate (int a, int b)
{
return a * b;
};
int c = cacl(2, 3);
}
结合Lambda表达式使用
public static void Main(string[] args)
{
Func<int, int, int> cacl = (x, y) => { return x * y; };
int c = cacl(2, 3);
}
Action
Action是无返回值的泛型委托,可以接受0个至16个传入参数。委托函数的参数类型和定义T类型参数一一对应。
Action<T>
Action<T1,T2>
声明Action
public static void Main(string[] args)
{
Action<string name, int age) say = Say;
say("ww", "18");
}
private static void Say(string name, int age)
{
Console.WriteLine($"我叫{name},今年{age}");
}
结合匿名函数使用
Action<string, int> say = delegate(string name, int age) =>
{
Console.WriteLine($"我叫{name},今年{age}");
};
say("ww", 18);
结合Lambda表达式使用
Action<string, int> say = (name, age) =>
{
Console.WriteLine($"我叫{name},今年{age}");
};
say("ww", 18);
predicate
predicate 是返回bool型的泛型委托,只能接受一个传入参数。类似于Func<T,bool>。在List<>中的Find、Exists方法,形参均为Predicate委托。如下:
public T Find(Predicate<T> match);
简单使用
在List中使用
具体方法定义为:public bool Exists(Predicate match);
//Lambda表达式
bool isExists = testList.Exists(t => t.Index == 7);
//委托方法
isExists = testList.Exists(JudgeExists);
public bool JudgeExists()
{
if(....)//当t.Index == 7存在时
{
return true;
}
return false;
}
```