委托-异步调用-泛型委托-匿名方法-Lambda表达式-事件【转】

1. 委托

From: http://www.cnblogs.com/daxnet/archive/2008/11/08/1687014.html

类是对象的抽象,而委托则可以看成是函数的抽象。一个委托代表了具有相同参数列表和返回值的所有函数。

  1. class Program
  2. {
  3. delegate int CalculateDelegate(int a, int b);
  4. int add(int a, int b)
  5. {
  6. return a + b;
  7. }
  8. static void Main(string[] args)
  9. {
  10. CalculateDelegate d = new Program().add;
  11. //CalculateDelegate d = new CalculateDelegate(new Program().add);
  12. Console.WriteLine(d(1, 2));
  13. Console.ReadKey();
  14. }
  15. }
    class Program
{
delegate int CalculateDelegate(int a, int b); int add(int a, int b)
{
return a + b;
} static void Main(string[] args)
{
CalculateDelegate d = new Program().add;
//CalculateDelegate d = new CalculateDelegate(new Program().add);
Console.WriteLine(d(1, 2));
Console.ReadKey();
}
}

委托作为参数,在C#中非常常见。比如线程的创建,需要给一个ThreadStart或者ParameterizedThreadStart委托作为参数,而在线程执行的时候,将这个参数所指代的函数用作线程执行体。再比如:List<T>类型的Find方法的参数也是一个委托,它把“怎么去查找”或者说“怎么样才算找到”这个问题留给了开发人员。这有点像模板模式。

委托作为返回值一般会用在“根据不同情况决定使用不同的委托”这样的情形下。这有点像工厂模式。

2. 异步调用

From: http://www.cnblogs.com/daxnet/archive/2008/11/10/1687013.html

异步通过委托来完成。.net使用delegate来"自动"生成的异步调用是使用了另外的线程(而且是线程池线程)。

  1. class Program
  2. {
  3. static TimeSpan Boil()
  4. {
  5. DateTime begin = DateTime.Now;
  6. Console.WriteLine("水壶:开始烧水...");
  7. Thread.Sleep(6000);
  8. Console.WriteLine("水壶:水已经烧开了!");
  9. return DateTime.Now - begin;
  10. }
  11. delegate TimeSpan BoilingDelegate();
  12. static void Main(string[] args)
  13. {
  14. Console.WriteLine("小文:将水壶放在炉子上");
  15. BoilingDelegate d = new BoilingDelegate(Boil);
  16. IAsyncResult result = d.BeginInvoke(BoilingFinishedCallback, null);
  17. Console.WriteLine("小文:开始整理家务...");
  18. for (int i = 0; i < 20; i++)
  19. {
  20. Console.WriteLine("小文:整理第{0}项家务...", i + 1);
  21. Thread.Sleep(1000);
  22. }
  23. }
  24. static void BoilingFinishedCallback(IAsyncResult result)
  25. {
  26. AsyncResult asyncResult = (AsyncResult)result;
  27. BoilingDelegate del = (BoilingDelegate)asyncResult.AsyncDelegate;
  28. Console.WriteLine("(烧水一共用去{0}时间)", del.EndInvoke(result));
  29. Console.WriteLine("小文:将热水灌到热水瓶");
  30. Console.WriteLine("小文:继续整理家务");
  31. }
  32. }
class Program
{
static TimeSpan Boil()
{
DateTime begin = DateTime.Now;
Console.WriteLine("水壶:开始烧水...");
Thread.Sleep(6000);
Console.WriteLine("水壶:水已经烧开了!");
return DateTime.Now - begin;
}
delegate TimeSpan BoilingDelegate(); static void Main(string[] args)
{
Console.WriteLine("小文:将水壶放在炉子上");
BoilingDelegate d = new BoilingDelegate(Boil);
IAsyncResult result = d.BeginInvoke(BoilingFinishedCallback, null);
Console.WriteLine("小文:开始整理家务...");
for (int i = 0; i < 20; i++)
{
Console.WriteLine("小文:整理第{0}项家务...", i + 1);
Thread.Sleep(1000);
}
} static void BoilingFinishedCallback(IAsyncResult result)
{
AsyncResult asyncResult = (AsyncResult)result;
BoilingDelegate del = (BoilingDelegate)asyncResult.AsyncDelegate;
Console.WriteLine("(烧水一共用去{0}时间)", del.EndInvoke(result));
Console.WriteLine("小文:将热水灌到热水瓶");
Console.WriteLine("小文:继续整理家务");
}
}

EndInvoke会使得调用线程阻塞,直到异步函数处理完成。EndInvoke会使得调用线程阻塞,直到异步函数处理完成。EndInvoke会使得调用线程阻塞,直到异步函数处理完成。EndInvoke会使得调用线程阻塞,直到异步函数处理完成。EndInvoke调用的返回值也就是异步处理函数的返回值。

3. 泛型委托

[Serializable]

publicdelegatevoid EventHandler<TEventArgs>(object sender, TEventArgs e) where TEventArgs: EventArgs;

  1. class IntEventArgs : System.EventArgs
  2. {
  3. public int IntValue { get; set; }
  4. public IntEventArgs() { }
  5. public IntEventArgs(int value)
  6. { this.IntValue = value; }
  7. }
  8. class StringEventArgs : System.EventArgs
  9. {
  10. public string StringValue { get; set; }
  11. public StringEventArgs() { }
  12. public StringEventArgs(string value)
  13. { this.StringValue = value; }
  14. }
  15. class Program
  16. {
  17. static void PrintInt(object sender, IntEventArgs e)
  18. {
  19. Console.WriteLine(e.IntValue);
  20. }
  21. static void PrintString(object sender, StringEventArgs e)
  22. {
  23. Console.WriteLine(e.StringValue);
  24. }
  25. static void Main(string[] args)
  26. {
  27. EventHandler<IntEventArgs> ihandler =
  28. new EventHandler<IntEventArgs>(PrintInt);
  29. EventHandler<StringEventArgs> shandler =
  30. new EventHandler<StringEventArgs>(PrintString);
  31. ihandler(null, new IntEventArgs(100));
  32. shandler(null, new StringEventArgs("Hello World"));
  33. }
  34. }
class IntEventArgs : System.EventArgs
{
public int IntValue { get; set; }
public IntEventArgs() { }
public IntEventArgs(int value)
{ this.IntValue = value; }
} class StringEventArgs : System.EventArgs
{
public string StringValue { get; set; }
public StringEventArgs() { }
public StringEventArgs(string value)
{ this.StringValue = value; }
} class Program
{
static void PrintInt(object sender, IntEventArgs e)
{
Console.WriteLine(e.IntValue);
} static void PrintString(object sender, StringEventArgs e)
{
Console.WriteLine(e.StringValue);
} static void Main(string[] args)
{
EventHandler<IntEventArgs> ihandler =
new EventHandler<IntEventArgs>(PrintInt);
EventHandler<StringEventArgs> shandler =
new EventHandler<StringEventArgs>(PrintString); ihandler(null, new IntEventArgs(100));
shandler(null, new StringEventArgs("Hello World"));
}
}

4. 匿名方法

http://www.cnblogs.com/daxnet/archive/2008/11/12/1687011.html

只需要给出方法的参数列表(甚至也可以不给)以及方法具体实现,而不需要关心方法的返回值,更不必给方法起名字。最关键的是,只在需要的地方定义匿名方法,保证了代码的简洁。比如用于委托作为函数参数。

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. List<string> names = new List<string>();
  6. names.Add("Sunny Chen");
  7. names.Add("Kitty Wang");
  8. names.Add("Sunny Crystal");
  9. List<string> found = names.FindAll(
  10. delegate(string name)
  11. {
  12. return name.StartsWith("sunny",
  13. StringComparison.OrdinalIgnoreCase);
  14. });
  15. if (found != null)
  16. {
  17. foreach (string str in found)
  18. Console.WriteLine(str);
  19. }
  20. }
  21. }
class Program
{
static void Main(string[] args)
{
List<string> names = new List<string>();
names.Add("Sunny Chen");
names.Add("Kitty Wang");
names.Add("Sunny Crystal"); List<string> found = names.FindAll(
delegate(string name)
{
return name.StartsWith("sunny",
StringComparison.OrdinalIgnoreCase);
}); if (found != null)
{
foreach (string str in found)
Console.WriteLine(str);
}
}
}

5. Lambda表达式

http://www.cnblogs.com/daxnet/archive/2008/11/14/1687010.html

从委托的角度来看,Lambda表达式与匿名方法没有区别。Lambda表达式的定义方式为:“([参数列表]) => 表达式”。

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. List<string> names = new List<string>();
  6. names.Add("Sunny Chen");
  7. names.Add("Kitty Wang");
  8. names.Add("Sunny Crystal");
  9. List<string> found = names.FindAll
  10. (
  11. // Lambda Expression Implementation
  12. name => name.StartsWith(
  13. "sunny",
  14. StringComparison.OrdinalIgnoreCase)
  15. );
  16. if (found != null)
  17. {
  18. foreach (string str in found)
  19. Console.WriteLine(str);
  20. }
  21. }
  22. }
class Program
{
static void Main(string[] args)
{
List<string> names = new List<string>();
names.Add("Sunny Chen");
names.Add("Kitty Wang");
names.Add("Sunny Crystal"); List<string> found = names.FindAll
(
// Lambda Expression Implementation
name => name.StartsWith(
"sunny",
StringComparison.OrdinalIgnoreCase)
); if (found != null)
{
foreach (string str in found)
Console.WriteLine(str);
}
}
}

6. 事件

http://www.cnblogs.com/daxnet/archive/2008/11/21/1687008.html

事件由委托定义。事件的触发方只需要确定好事件处理函数的签名即可。也就是说,触发方只需要定义在事件发生时需要传递的参数,而在订阅方,只需要根据这个签名定义一个处理函数,然后将该函数“绑定”到事件列表,就可以通过签名中的参数,对事件做相应的处理。

上一篇:linux awk的使用


下一篇:OpenCASCADE Conic to BSpline Curves-Circle