Day2 学习WPF之委托以致用
1、委托(delegate)是函数指针的“升级版”
①用函数名称直接调用
#include<studio.h>
int Add(int a,int b)
{
int result = a + b;
return result;
}
int Sub(int a,int b)
{
int result = a - b;
return result;
}
int main()
{
int x = 100;
int y = 200;
int z = 0;
z = Add(x,y);//通过函数名称直接调用
printf("%d+%d=%d/n",x,y,z);
z = Sub(x,y);//通过函数名称直接调用
printf("%d+%d=%d/n",x,y,z);
system("pause")
return 0;
}
②用函数指针间接调用
#include<studio.h>
typedef int(*Calc)(int a,int b);//定义数据类型;函数指针名为Calc,形参为两个int类型的值,返回值为int类型
int Add(int a,int b)
{
int result = a + b;
return result;
}
int Sub(int a,int b)
{
int result = a - b;
return result;
}
int main()
{
int x = 100;
int y = 200;
int z = 0;
Calc funcPoint1 = &Add;//申明函数指针类型的变量,取Add函数的地址
Calc funcPoint2 = ⋐
z = funcPoint1(x,y);//通过函数名称直接调用
printf("%d+%d=%d/n",x,y,z);
z = funcPoint2(x,y);//通过函数名称直接调用
printf("%d+%d=%d/n",x,y,z);
system("pause")
return 0;
}
2、一切皆地址
变量(数据):是以某个地址为起点的一段内存中所存储的值
函数(算法):是以某个地址为起点的一段内存中所存储的一组机器语言指令
直接调用:通过函数名来调用函数,CPU通过函数名直接获得函数所在地址并开始执行->返回
间接调用:通过函数指针来调用函数,CPU通过读取函数指针存储的值获得函数所在地址并开始执行->返回
3、委托的简单使用
① 在C/C++中需要先申明函数指针的类型,才能使用函数指针;而在C#的类库中,已经为我们准备好了很多可以直接使用的委托类型。例如Action、Function等
- Action委托:无输入参数与返回值
- Function委托:一共有17种重载类型可选
按↓键一共有17种重载类型可选
【例如】第3个重载类型代表目标方法的参数类型:T1,T2两个参数,一个返回值
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WpfApplicationDemo2_20.Commands
{
class DelegateExample
{
static void Main(string[] args)
{
Calculator calculator = new Calculator();
Action action = new Action(calculator.Report);//report后面没有加(),因为在这里只是需要这个方法的方法名,而不是在此处调用此方法
#region 方法Action,该方法不具有参数,并且没有返回值
//此处的意思是指Action类型的action方法指向calculator.Report的这个方法
calculator.Report();//直接调用Report这个方法
action.Invoke();//间接调用Report这个方法
action();//模仿函数指针的这种方法间接调用
#endregion
//Function委托,泛型委托
Func<int, int, int> fun1 = new Func<int, int, int>(calculator.Add);
Func<int, int, int> fun2 = new Func<int, int, int>(calculator.Add);
int x = 100;
int y = 200;
int z = 0;
//间接调用
z = fun1.Invoke(x, y);
Console.WriteLine(z);
z = fun2.Invoke(x, y);
Console.WriteLine(z);
//模仿函数指针的这种方法间接调用
z = fun1(x, y);
Console.WriteLine(z);
z = fun2(x, y);
Console.WriteLine(z);
}
}
class Calculator
{
public void Report()
{
Console.WriteLine("I have 3 methods.");
}
public int Add(int a,int b)
{
int result = a + b;
return result;
}
public int Sub(int a, int b)
{
int result = a - b;
return result;
}
}
}
② 委托是一种类(class),类是数据类型所以委托也是一种数据类型,但它的声明方式与一般的类不同。
- 自定义委托类型
委托与所封装的方法必须保持“类型一致”,参数名字不一定要相同;
public delegate double Calc(double x, double y);
public double Add(double a, double b)
public double Sub(double a, double b)
public double Mul(double a, double b)
public double Div(double a, double b)
声明委托的位置:声明在名称空间体里面,与其他的类同一级别,避免写入其他类里面,成为嵌套类;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WpfApplicationDemo2_20.Commands
{
public delegate double Calc(double x, double y);
//自定义委托类型
//public表示这种数据类型从什么地方都可以访问,是公开的
//delegate表明要声明一种委托,紧接着double表示目标方法的返回值类型
//Calc为目标方法的名称,圆括号()内写上目标方法的参数列表
class DelegateMyselfExample
{
static void program()
{
Calculate calculate = new Calculate();//创建calculate类的变量和实例,通过实例才可以访问实例的变量和方法
Calc calc1 = new Calc(calculate.Add);//创建委托Calc的变量和实例,委托的构造函数要求在()内传递一个方法,这个方法就是委托指向的目标方法
Calc calc2 = new Calc(calculate.Sub);
Calc calc3 = new Calc(calculate.Mul);
Calc calc4 = new Calc(calculate.Div);
double a = 100;
double b = 200;
double c = 0;
c = calc1.Invoke(a, b);// c = calc1(a, b);
Console.WriteLine(c);
c = calc2.Invoke(a, b);// c = calc2(a, b);
Console.WriteLine(c);
c = calc3.Invoke(a, b);// c = calc3(a, b);
Console.WriteLine(c);
c = calc4.Invoke(a, b);// c = calc4(a, b);
Console.WriteLine(c);
}
}
class Calculate
{
public double Add(double a, double b)
{
double result = a + b;
return result;
}
public double Sub(double a, double b)
{
double result = a - b;
return result;
}
public double Mul(double a, double b)
{
double result = a * b;
return result;
}
public double Div(double a, double b)
{
double result = a / b
return result;
}
}
}