当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > C#教程:使用lambda表达式记录事件日志

ASP.NET
FreeTextBox(版本3.1.6)在ASP.Net 2.0中使用方法
.NET 常用功能和代码小结
在 .NET Framework 2.0 中未处理的异常导致基于 ASP.NET 的应用程序意外退出
asp.net IList查询数据后格式化数据再绑定控件
asp.net sql存储过程
asp.net 简单实现禁用或启用页面中的某一类型的控件
asp.net(c#)获取内容第一张图片地址的函数
The remote procedure call failed and did not execute的解决办法
ASP.NET 在线文件管理
asp.net 读取并修改config文件实现代码
ASP.NET Cookie 操作实现
asp.net Silverlight中的模式窗体
Silverlight中动态获取Web Service地址
asp.net Silverlight应用程序中获取载体aspx页面参数
asp.net 水晶报表隔行换色实现方法
asp.net 获取Gridview隐藏列的值
手动把asp.net的类生成dll文件的方法
asp.net 使用ObjectDataSource控件在ASP.NET中实现Ajax真分页
动态指定任意类型的ObjectDataSource对象的查询参数
asp.net Md5的用法小结

ASP.NET 中的 C#教程:使用lambda表达式记录事件日志


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-28   浏览: 92 ::
收藏到网摘: n/a

使用List<T>和事件的简单例子

如果你记得List<T>当中的FindAll()方法, 其要求一个Predicate<T>参数并且返回一个新的列表, 该列表包含的所有元素都满足输入断言(predicate). Sort方法要求一个Comparison<T>参数然后按序排列整个列表. 以下的例子使用了lambda表达式提供了委托实例给每一个方法. 示例数据是不同电影的名称和发行年限. 我们将打印出原始的列表, 然后创建并打印出一个过滤的只包含老电影的列表, 并按名称排序打印出原始列表.

 1: class Film
 2: {
 3: public string Name { get; set; }
 4: public int Year { get; set; }
 5: public override string ToString()
 6: {
 7: return string.Format("Name={0}, Year={1}", Name, Year);
 8: }
 9: }
 10: ...
 11: var films = new List<Film>
 12: {
 13: new Film {Name="Jaws", Year=1975},
 14: new Film {Name="Singing in the Rain", Year=1952},
 15: new Film {Name="Some Like It Hot", Year=1959},
 16: new Film {Name="The Wizard of Oz", Year=1939},
 17: new Film {Name="It's a Wonderful Life", Year=1946},
 18: new Film {Name="American Beauty", Year=1999},
 19: new Film {Name="High Fidelity", Year=2000},
 20: new Film {Name="The Usual Suspects", Year=1995}
 21: };
 22: Action<Film> print = film => { Console.WriteLine(film); };
 23: films.ForEach(print);
 24: films.FindAll(film => film.Year < 1960)
 25: .ForEach(print);
 26: films.Sort((f1, f2) => f1.Name.CompareTo(f2.Name));
 27: films.ForEach(print);

代码的前半部分主要是数据的准备, 我们使用了匿名类, 其是一个泛型列表实例. 在开始使用这个列表之前, 我们创建了一个委托实例, 我们将会使用这个实例来打印列表.这就是为什么我使用了一个变量来保存该实例, 而不是每次都使用一个单独的lambda表达式. 它仅仅打印了一个元素, 但是将它传递给List<T>.ForEach方法我们可以整个列表元素都输出到控制台.

我们打印的第一个列表是没有任何编辑的原始列表, 接下来我们查找并打印出了所有发行年限在1960年之前的电影. 我们使用了另外一个lambda表达式来完成这项工作, 列表中的每一个项都会执行该表达式——它用于决定该元素是否应该出现在新的过滤列表当中. 源代码当中使用了lambda表达式作为方法参数, 然而编译器实际上是类似下面代码一样创建了一个方法:

 1: private static bool SomeAutoGeneratedName(Film film)
 2: {
 3: return film.Year < 1960;
 4: }

FindAll方法调用将会类似下面这样:

 1: films.FindAll(new Predicate<Film>(SomeAutoGeneratedName))

这里对于lambda表达式的支持与C# 2中的匿名方法一致, 这就是编译器的聪明之处. (实际上, 微软的编译器在这个例子中甚至还更加聪明——它甚至能够意识到如果代码再次被调用, 委托类型可能会再次被使用, 因此会将它缓存.)

排序部分同样也是使用了一个lambda表达式, 其通过名字进行了比较. 我不得不承认显式调用CompareTo有点丑陋, 在下面一节当中我们将看到如何使用OrderBy扩展方法来更简洁的排序.

使用lambda表达式记录事件日志

 1: static void Log(string title, object sender, EventArgs e)
 2: {
 3: Console.WriteLine("Event: {0}", title);
 4: Console.WriteLine(" Sender: {0}", sender);
 5: Console.WriteLine(" Arguments: {0}", e.GetType());
 6: foreach (PropertyDescriptor prop in
 7: TypeDescriptor.GetProperties(e)){
 8: string name = prop.DisplayName;
 9: object value = prop.GetValue(e);
 10: Console.WriteLine(" {0}={1}", name, value);
 11: }
 12:  
 13: ...
 14: Button button = new Button();
 15: button.Text = "Click me";
 16: button.Click += (src, e) => { Log("Click", src, e); };
 17: button.KeyPress += (src, e) => { Log("KeyPress", src, e); };
 18: button.MouseClick += (src, e) => { Log("MouseClick", src, e); };
 19: Form form = new Form();
 20: form.AutoSize=true;
 21: form.Controls.Add(button);
 22: Application.Run(form);

上述的代码使用了lambda表达式来传递事件名和参数到Log方法, 该方法记录了事件的一些详细信息. 我们并没有记录源事件的所有信息, 而仅仅是调用了ToString()重载方法, 因为控件本身承载了大量的信息. 实际上, 我们使用了反射来遍历了属性的descriptor信息, 这里是一个可能的输出结果:

 1: Event: Click
 2: Sender: System.Windows.Forms.Button, Text: Click me
 3: Arguments: System.Windows.Forms.MouseEventArgs
 4: Button=Left
 5: Clicks=1
 6: X=53
 7: Y=17
 8: Delta=0
 9: Location={X=53,Y=17}
 10: Event: MouseClick
 11: Sender: System.Windows.Forms.Button, Text: Click me
 12: Arguments: System.Windows.Forms.MouseEventArgs
 13: Button=Left
 14: Clicks=1
 15: X=53
 16: Y=17
 17: Delta=0
 18: Location={X=53,Y=17}

所有的这些不通过lambda表达式当然也可以做到, 不过使用lambda表达式相比其他的做法更加简洁.