首页 / 软件开发 / C# / c#扩展方法奇思妙用高级篇三:Enumerable.Cast<T>应用
c#扩展方法奇思妙用高级篇三:Enumerable.Cast<T>应用2010-04-23 博客园 鹤冲天Enumerable.Cast<T>用于将IEnumerable转换为泛型版本IEnumerable<T>。转换后可尽情享用Enumerable的其它方法(如Where、Select),给我们的编码带来极大便利。但MSDN中仅给出一个转换ArrayList的例子,很多人看了感觉现在都在用List<T>,还有谁会用ArrayList,Cast<T>没多少用处,除非处理一些之前遗留的一些代码。其实Cast<T>并非如此简单,它可以用在很多地方。先看MSDN中举的例子吧:1 System.Collections.ArrayList fruits = new System.Collections.ArrayList();
2 fruits.Add("apple");
3 fruits.Add("mango");
4
5 IEnumerable<string> query = fruits.Cast<string>();
6 foreach (string fruit in query) Console.WriteLine(fruit);
这个例子比较简单,很容易理解。同样.Net 1.x中的其它几个集合类也可如上使用,如Array、非泛型版的List...打断,有没有非泛型版的List?我没太用过.Net 1.x,不太清楚,不过窗体控件中是有个List控件(ASP.Net)和一个ListView控件(WinForm)。就以ListView为例子吧,ListView控件可以包含很多项,也可以说是一个集合,就让我们来看看它的Items属性吧!1 public class ListView : Control
2 {
3
4 public ListView.ListViewItemCollection Items { get; }
5
6 public class ListViewItemCollection : IList, ICollection, IEnumerable { }
7
8 }
ListView的Items类型是ListView.ListViewItemCollection,这个ListViewItemCollection实现了IEnumerable。ListView.Items正是一个非泛型的集合,因此可以应用Cast<T>。以下代码假定 listBox 数据绑定在一个Employee的集合上:1 int count = listBox.Items.Cast<Employee>().Count();
2 bool b = listBox.Items.Cast<Employee>().Any(e => e.FirstName == "Bob");
(当然,如果有Employee的集合的引用,就不用Cast了,这里只是示例)同样Cast<T>可以用在ComboBox、DataGridView、TreeNode上:1 //ComboBox
2 var v1 = comboBox.Items.Cast<People>();
3 //DataGridView
4 var v2 = dataGridView.SelectedRows.Cast<DataGridViewRow>();
5 var v3 = dataGridView.SelectedColumns.Cast<DataGridViewColumn>();
6 var v4 = dataGridView.SelectedCells.Cast<DataGridViewCell>();
7 //TreeNode
8 var v5 = treeNode.Nodes.Cast<TreeNode>();
这几个应用中应该第 4 行的应用最多,获取选中行是DataGridView使用最频繁的操作之一。试看下面代码:1 //计算平均年龄
2 int age = dataGridView.SelectedRows.Cast<Employee>().Average(p=>p.Age);
3 //统计所在城市
4 string[] cities = dataGridView.SelectedRows.Cast<Employee>().Select(p => p.City).Distinct();
用了Cast<T>,我们的代码很精简。Cast<T>甚至还可以用在所有控件的基类Control上,它的Controls属性也是非泛型的!1 //Control
2 var v6 = control.Controls.Cast<Control>();