一、函数重载
函数的重载指的是在一个类中,有相同的名字的函数,但是函数参数不同的函数。函数的实现内容不要求一样。
注意:仅仅有返回类型不同的情况,都不是重载函数。
public int Add(int a,int b,int c)
{
}
public int Add(int a,int b)
{
}
public void Add(double a)
{
}
二、函数委托
委托(delegate)是一种可以把引用存储为函数的类型。委托的声明非常类似于函数,但不带函数体,且要使用delegate 关键字。
委托是c#最好的一个特性,它为后来的很多特性都打下了基础。委托使得一个方法可以作为另一个方法的参数进行传递,这就是委托最大的作用。
C#的委托(Delegate)类似c或者c++的函数指针,但是,委托是类型安全和可靠的。委托也是事件的基础。**一旦为委托分配了方法,委托将与该方法具有完全相同的行为。**与委托签名匹配的任何方法都可以分配给当前委托。
声明委托(Delegate)
//有参数有返回值
public delegate int CalcDelegate(int a,int b);
//实例化委托
CalcDelegate calc = new CalcDelegate(Add);
//或者
CalcDelegate calc = Add;
public int Add(int a,int c)
{
return a+c;
}
例子1:传递方法
using System;
delegate int CalcDelegate(int n, int b);
namespace DelegateApp1
{
class TestDelegate1
{
public int Add(int p, int c)
{
return p + c;
}
public int Mult(int q, int c,int g)
{
return q * c * g;
}
}
class TestDelegate
{
public static int Add(int p, int c)
{
return p + c;
}
public static int Mult(int q,int c)
{
return q * c;
}
private static int Othe(int v, int h)
{
return v - h;
}
static void Main(string[] args)
{
//创建委托实例
CalcDelegate cd1 = new CalcDelegate(Add);
CalcDelegate cd2 = new CalcDelegate(Mult);
//使用委托对象调用方法
int result1 = cd1(12, 22);
Console.WriteLine("Value of Num: {0}", result1);
int result2 = cd2(5, 6);
Console.WriteLine("Value of Num: {0}", result2);
//在一个类中直接使用方法,不用实例化
int result3 = Add(1, 2);
//类实例
TestDelegate1 cd3 = new TestDelegate1();
int result4 = cd3.Add(1,2);
Console.WriteLine("Value of Num: {0}", result4);
int result5 = cd3.Mult(1, 2, 3);
Console.WriteLine("Value of Num: {0}", result5);
Console.ReadLine();
}
}
}
例子2:为什么用委托
例如我们要实现一个打招呼的方法,而每个国家打招呼的方式都不一样,刚开始我们可能会像下面这样实现打招呼的方法:
public void Greeting(string name,string language)
{
switch (language)
{
case "zh-cn":
ChineseGreeting(name);
break;
case "en-us":
EnglishGreeting(name);
break;
default:
EnglishGreeting(name);
break;
}
}
public void EnglishGreeting(string name )
{
Console.WriteLine("Hello, " + name);
}
public void ChineseGreeting(string name)
{
Console.WriteLine("你好, " + name);
}
若后续我们需要添加德国、日本等打招呼方法,就必须修改Greeting方法内的case语句,来适应新的需求,这样特别不方便。有了委托,我们就可以把函数作为参数,并像如下代码实现Greeting方法:
class Program
{
public delegate void GreetingDelegate(string name);
//GreetingDelegate该委托传递的是方法
static void Main(string[] args)
{
//引入委托
Program p = new Program();
p.Greeting("小叶", p.ChineseGreeting);
p.Greeting("Tommy Li", p.EnglishGreeting);
Console.Read();
}
public void Greeting(string name, GreetingDelegate callback)
{
callback(name);
}
public void EnglishGreeting(string name)
{
Console.WriteLine("Hello, " + name);
}
public void ChineseGreeting(string name)
{
Console.WriteLine("你好, " + name);
}
}
实例3:委托可以多播,用+=来添加到调用列表,-=来移除调用列表。
static void Main(string[] args)
{
// 创建委托实例
CalcDelegate cd=null;
CalcDelegate cd1 = new CalcDelegate(Add);
CalcDelegate cd2 = new CalcDelegate(Mult);
cd+=cd1;
cd+=cd2;
Console.Writeline("num:{0}",cd(5,6));
Console.ReadKey();
}
委托实例4:函数回调
最常见的回调应用之一,是计时器到点时调用的函数。涉及到的类型(.NET有三个计时器类型,这个是线程名称空间System.Threading里的Timer):
public sealed Timer(TimerCallBack callback, object state, int dueTime, int period);
public delegate void TimeCallBack(object state);
Timer类型中,callback是一个委托TimerCallBack的对象;state是调用时的状态参数,可以灵活应用;dueTime是计时器开始计时的等待时间;period是计时周期,每完成一个周期就调用方法callback
2.
回调函数CalllBack的委托定义表明,计时器类Timer到点时回调的函数不能有返回类型,但必须有一个参数object型的参数。注意,此处委托的所谓逆变不能用了