您的位置:首页 > 编程语言 > C#

C#匿名方法和Lambda表达式

2016-04-16 11:15 411 查看
C#匿名方法和Lambda表达式

当一个调用者想监听传来的事件的时候,它必须定义一个唯一的与相关委托签名匹配的方法。

在事件注册时直接将一个委托与一段代码相关联,这种代码叫做匿名方法。

namespace ConsoleApplication1
{
class Program
{
public class Car
{
// 属性
public string CarName { get; set; }
public int CurrentSpeed { get; set; }
public int MaxSpeed { get; set; }

// 成员
private bool carIsBroken;

// 构造函数
public Car() { MaxSpeed = 180; }
public Car(string name, int maxSpd, int curSpd)
{
CarName = name;
CurrentSpeed = curSpd;
MaxSpeed = maxSpd;
//carIsBroken = false;
}

// 创建一个委托用于对Car事件的响应处理。
//public delegate void CarEngineHandler(string msg);
public delegate void CarEngineHandler(object sender, CarEventArgs e);

// Car类可以发送的事件
public event CarEngineHandler eCarIsBroken;
public event CarEngineHandler eOverSpeedAlarm;

public void Accelerate(int delta)
{
// 如果汽车已坏,触发eCarIsBroken事件
if (carIsBroken)
{
if (eCarIsBroken != null)    // 触发事件!
{
//eCarIsBroken("Car is broken,can't drive now!");
eCarIsBroken(this,new CarEventArgs("Car is broken,can't drive now!"));
}
}
else
{
CurrentSpeed += delta;
}

// 超速提醒
if (20 == MaxSpeed - CurrentSpeed && eCarIsBroken != null)  // 触发事件!
{
//eOverSpeedAlarm("Alarm: Going too fast, drive slowly!");
eOverSpeedAlarm(this,new CarEventArgs("Alarm: Going too fast, drive slowly!"));
}

if (CurrentSpeed >= MaxSpeed)
{
carIsBroken = true;
}
else
{
Console.WriteLine("CurrentSpeed = {0}", CurrentSpeed);
}
}
}

// 利用EventArgs的派生类,来传递数据。
public class CarEventArgs : EventArgs
{
public readonly string msg;
public CarEventArgs(string message)
{
msg = message;
}
}

public static void TheCarIsBroken(string msg)
{
Console.WriteLine(msg);
}

static void Main(string[] args)
{
Car myCar = new Car("Audio Q5", 200, 60);

// 采用匿名的方式注册事件处理程序, 匿名方法的最后需要有一个分号结束
myCar.eOverSpeedAlarm += delegate(object sender, CarEventArgs e)
{
Console.WriteLine("{0}:{1}", sender, e.msg);
};

myCar.eCarIsBroken += delegate(object sender, CarEventArgs e)
{
Console.WriteLine("{0}:{1}", sender, e.msg);
};

for (int i = 0; i < 12; i++)
{
myCar.Accelerate(20);
}

Console.ReadLine();
}
}
}


Lambda表达式是匿名方法的简单表达方式,从而彻底的简化了对委托的使用。

Lambada表达式是这样编写的:

首先定义一个参数列表,随后加上“=>"标记,然后加上处理这些参数的语句。

Lambda表达式的参数可以使显示类型化,也可以使隐式类型化的。

举例说明如下:利用泛型List<T>的FindAll()方法从一组数据中找出所有的偶数。

方法一:使用传统的委托方法

namespace ConsoleApplication1
{
class Program
{
static void TraditionalDelegate()
{
// 创建整数列表
List<int> myList = new List<int> { };
myList.AddRange(new int[]{ 1, 2, 3, 4, 5, 9, 10, 21, 30, 68 });

// 使用传统泛型委托语法调用FindAll
Predicate<int> callback = new Predicate<int>(IsEvenNumber);
List<int> evenNumbers = myList.FindAll(callback);

// 输出结果
foreach( int evenNumber in evenNumbers)
{
Console.WriteLine("{0},",evenNumber);
}
}

// Predicate 委托的目标方法
static bool IsEvenNumber(int number)
{
return (0 == number % 2 ? true : false);
}

static void Main(string[] args)
{
TraditionalDelegate();
Console.ReadLine();
}
}


方法二:使用匿名方法:

// 使用传匿名委托语法调用FindAll
List<int> evenNumbers = myList.FindAll(
delegate(int i)
{
return 0 == i % 2;
});


方法三:采用Lambda表达式

// 使用Lambda表达式
List<int> evenNumbers = myList.FindAll(
          i =>
0 == (i % 2)
);


至此,我们用Lambda表达式来更新之前写的Car 事件

static void Main(string[] args)
{
Car myCar = new Car("Audio Q5", 200, 60);

// 使用Lambda表达式来挂起事件
myCar.eOverSpeedAlarm += (sender, e) =>
{
Console.WriteLine(e.msg);
};
myCar.eCarIsBroken += (sender, e) =>
{
Console.WriteLine(e.msg);
};

for (int i = 0; i < 12; i++)
{
myCar.Accelerate(20);
}

Console.ReadLine();
}


总结如下:

1. delegate 关键字间接的构造了一个派生自MuticastDelegate的类,委托对象保存一个方法列表。可以被同步调用(Invoke()),或异步调用(BeginInvoke()和EndInvoke())

2. event 关键字简化了事件发送到调用者的处理过程。

3. 匿名方法可以直接将一段代码与指定事件相关联。Lambda表达式是匿名方法的简化表达方式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: