c# 委托类似于c语言或c++中函数的指针。委托是一个引用类型变量,它保存对方法的引用。 引用可以在运行时更改。
委托一般用于实现事件和回调方法。所有委托都隐式地从system.delegate
类派生。
委托声明确定委托可引用的方法。委托可以引用一个方法,它具有与委托相同的签名。
例如,考虑下面一个委托:
public delegate int mydelegate (string s);
上述委托可用于引用具有单个字符串参数并返回int
类型变量的任何方法。
委托声明的语法是:
delegate <return type> <delegate-name> <parameter list>
当声明了一个委托类型后,必须要使用new
关键字创建一个委托对象,并将其与特定的方法相关联。创建代理时,传递给新表达式的参数类似于方法调用,但不包含方法的参数。 例如:
public delegate void printstring(string s);
...
printstring ps1 = new printstring(writetoscreen);
printstring ps2 = new printstring(writetofile);
以下示例演示了可以用于引用取整数参数并返回整数值的方法委托的声明,实例化和使用。
using system;
delegate int numberchanger(int n);
namespace delegateappl
{
class testdelegate
{
static int num = 10;
public static int addnum(int p)
{
num += p;
return num;
}
public static int multnum(int q)
{
num *= q;
return num;
}
public static int getnum()
{
return num;
}
static void main(string[] args)
{
//create delegate instances
numberchanger nc1 = new numberchanger(addnum);
numberchanger nc2 = new numberchanger(multnum);
//calling the methods using the delegate objects
nc1(25);
console.writeline("value of num: {0}", getnum());
nc2(5);
console.writeline("value of num: {0}", getnum());
console.readkey();
}
}
}
当上述代码被编译并执行时,它产生以下结果:
value of num: 35
value of num: 175
代理对象可以使用“+”
运算符来组合。一个委托调用它由两个委托组成。只能组合相同类型的委托。“-”
运算符可用于从组合委托中删除组件委托。
使用委托的这个属性,可以创建一个方法的调用列表,该方法将在调用委托时调用。这称为委托组播。以下程序演示了一个委托组播:
using system;
delegate int numberchanger(int n);
namespace delegateappl
{
class testdelegate
{
static int num = 100;
public static int addnum(int p)
{
num += p;
return num;
}
public static int multnum(int q)
{
num *= q;
return num;
}
public static int getnum()
{
return num;
}
static void main(string[] args)
{
//create delegate instances
numberchanger nc;
numberchanger nc1 = new numberchanger(addnum);
numberchanger nc2 = new numberchanger(multnum);
nc = nc1;
nc += nc2;
//calling multicast
nc(5);
console.writeline("value of num: {0}", getnum());
console.readkey();
}
}
}
当上述代码被编译并执行时,它产生以下结果:
value of num: 525
以下示例演示了使用委托。委托printstring
可用于引用方法,该方法将字符串作为输入,并且不返回任何内容。
使用这个委托来调用两个方法,第一个将字符串打印到控制台,第二个打印到一个文件中:
using system;
using system.io;
namespace delegateappl
{
class printstring
{
static filestream fs;
static streamwriter sw;
// delegate declaration
public delegate void printstring(string s);
// this method prints to the console
public static void writetoscreen(string str)
{
console.writeline("the string is: {0}", str);
}
//this method prints to a file
public static void writetofile(string s)
{
fs = new filestream("c:\\message.txt",
filemode.append, fileaccess.write);
sw = new streamwriter(fs);
sw.writeline(s);
sw.flush();
sw.close();
fs.close();
}
// this method takes the delegate as parameter and uses it to
// call the methods as required
public static void sendstring(printstring ps)
{
ps("hello world");
}
static void main(string[] args)
{
printstring ps1 = new printstring(writetoscreen);
printstring ps2 = new printstring(writetofile);
sendstring(ps1);
sendstring(ps2);
console.readkey();
}
}
}
当上述代码被编译并执行时,它产生以下结果:
the string is: hello world