委托
一.委托
委托可以理解为一种数据类型(delegate),后面根函数定义.
delegate void Del(int x);
委托概述
委托具有以下特点:
-
委托类似于 C++ 函数指针,但它是类型安全的。
-
委托允许将方法作为参数进行传递。
-
委托可用于定义回调方法。
-
委托可以链接在一起;例如,可以对一个事件调用多个方法。
-
方法不需要与委托签名精确匹配。有关更多信息,请参见协变和逆变。
-
C# 2.0 版引入了匿名方法的概念,此类方法允许将代码块作为参数传递,以代替单独定义的方法。
二.委托使用.
1.定义一个签名
2.定义委托变量,并为委托变量赋值(可以是静态方法/实例.方法).
3.调用.
delegate void Del(int i, double j); //1,定义一个签名
class MathClass
{
static void Main()
{
MathClass m = new MathClass();
// Delegate instantiation using "MultiplyNumbers"
Del d = m.MultiplyNumbers; //2定义一个委托变量,为委托变量赋值
// Invoke the delegate object.
System.Console.WriteLine("Invoking the delegate using 'MultiplyNumbers':");
for (int i = 1; i <= 5; i++)
{
d(i, 2); //3.调用
}
}
// Declare the associated method.
void MultiplyNumbers(int m, double n)
{
System.Console.Write(m * n + " ");
}
}
三.匿名方法 委托.
要将代码块传递为委托参数,创建匿名方法则是唯一的方法
将代码块赋值给一个匿名变量.
// Create a delegate instance
delegate void Del(int x);
// 将代码块赋值给一个委托
Del d = delegate(int k) { /*语句1...语句2 do some ... */ };
四.何时使用委托而不使用接口(C# 编程指南)
委托和接口都允许分离类型声明和实现。给定的接口可由任何类实现;可以为任何类中的方法创建委托,前提是该方法符合委托的方法签名。接口引用或委托都可由不了解实现该接口或委托方法的类的对象使用。既然存在这些相似性,那么何时应使用委托,何时又该使用接口呢?
在以下情况中使用委托:
-
当使用事件设计模式时。
-
当封装静态方法可取时。
-
当调用方不需要访问实现该方法的对象中的其他属性、方法或接口时。
-
需要方便的组合。
-
当类可能需要该方法的多个实现时。
在以下情况中使用接口:
-
当存在一组可能被调用的相关方法时。
-
当类只需要方法的单个实现时。
-
当使用接口的类想要将该接口强制转换为其他接口或类类型时。
-
当正在实现的方法链接到类的类型或标识时:例如比较方法:使用单一方法接口而不使用委托的一个很好的示例是 IComparable 或 IComparable。IComparable 声明 CompareTo 方法,该方法返回一个整数,以指定相同类型的两个对象之间的小于、等于或大于关系。IComparable 可用作排序算法的基础,虽然将委托比较方法用作排序算法的基础是有效的,但是并不理想。因为进行比较的能力属于类,而比较算法不会在运行时改变,所以单一方法接口是理想的。
五.协变.
class Mammals
{
}
class Dogs : Mammals
{
}
class Program
{
// Define the delegate.
public delegate Mammals HandlerMethod();
public static Mammals FirstHandler()
{
return null;
}
public static Dogs SecondHandler()
{
return null;
}
static void Main()
{
HandlerMethod handler1 = FirstHandler;
// Covariance allows this delegate.
HandlerMethod handler2 = SecondHandler;
}
}
六.逆变
System.DateTime lastActivity;
public Form1()
{
InitializeComponent();
lastActivity = new System.DateTime();
this.textBox1.KeyDown += this.MultiHandler; //works with KeyEventArgs
this.button1.MouseClick += this.MultiHandler; //works with MouseEventArgs
}
// Event hander for any event with an EventArgs or
// derived class in the second parameter
private void MultiHandler(object sender, System.EventArgs e)
{
lastActivity = System.DateTime.Now;
}
七.合并
delegate void Del(string s);
class TestClass
{
static void Hello(string s)
{
System.Console.WriteLine(" Hello, {0}!", s);
}
static void Goodbye(string s)
{
System.Console.WriteLine(" Goodbye, {0}!", s);
}
static void Main()
{
Del a, b, c, d;
// Create the delegate object a that references
// the method Hello:
a = Hello;
// Create the delegate object b that references
// the method Goodbye:
b = Goodbye;
// The two delegates, a and b, are composed to form c:
c = a + b;
// Remove a from the composed delegate, leaving d,
// which calls only the method Goodbye:
d = c - a;
System.Console.WriteLine("Invoking delegate a:");
a("A");
System.Console.WriteLine("Invoking delegate b:");
b("B");
System.Console.WriteLine("Invoking delegate c:");
c("C");
System.Console.WriteLine("Invoking delegate d:");
d("D");
}
}
输出
Invoking delegate a: Hello, A! Invoking delegate b: Goodbye, B! Invoking delegate c: Hello, C! Goodbye, C! Invoking delegate d: Goodbye, D!