| 文章内容 -
|
|
|
ASP.Net2.0的集合操作 --- List? 在我以前的一篇随笔中曾提到不要在代码中散布遍历集合的操作.而是将遍历集合的操作放入集合本身.
当时就想在.Net1.0中需要自己做Typed Collection,这样当然可以把遍历集合的操作放入集合本身.
可是在.Net2.0中提供了泛型机制,我总不能为了隐藏遍历集合的操作而复古(自己做Typed Collection)吧.
幸运的是发现.Net2.0已经为我想到这点了.你会发现在.Net2.0的List<T>中提供了ForEach(Action<T>)这么一个方法.
class Program
{
static void Main(string[] args)
{
List<string> strs = new List<string>();
strs.Add("hello");
strs.Add("world");
strs.ForEach(Console.WriteLine)
}
}
怎么样? 看不到foreach(string str in strs)这样的操作了吧.
为什么要这样做? 具体原因以及.Net1.0下的实现方法请见here(文章有点长, 耐心点喔, 看完应该有收获的)
不过, List<T>对我来说还不够完美. 它无法实现对集合中满足特定条件的所有成员做某件事.
也就是提供一个类似于下面这样的方法:
ForSpecification(Predicate<T>, Action<T>);
如果这样岂不是完美了? 既然做了ForEach为什么MS不做ForSpecification呢?
现在我要想实现这样的功能只能用Find(Predicate<T>)方法找出集合中符合条件的元素, 然后再对它进行遍历(真丑陋)
干脆象.Net1.0下自己实现一个集合操作的辅助类吧. 不过有了泛型的支持,实现方法肯定比以前的简单很多.不过目的和思想都是一样的.
class Algorithm
{
public static void ForSpecification<T>(IEnumerable<T> collection, Action<T> action, Predicate<T> filter)
{
foreach (T obj in collection)
{
if (filter(obj))
action(obj);
}
}
}
class Program
{
static void Main(string[] args)
{
IList<string> strs = new List<string>();
strs.Add("hello");
strs.Add("world");
strs.Add("hide");
Algorithm.ForSpecification<string>(
strs,
Console.WriteLine,
delegate(string str)
{
//return true; Hide will be output
return str.Contains("o"); //if string contains 'o' then output
});
}
}
ok? 即使不支持ForEach以及Find方法的集合也可以使用这个辅助类来完成相应的操作.
其实还可以在辅助类中添一些方法,比如让集合中的元素相加,并返回结果, 留给大家自己实现吧.
Feedback
#1楼 回复 引用 查看
2005-04-25 20:40 by CsOver
关注更多关于.net2.0的文章!
#2楼 回复 引用 查看
2005-05-05 22:09 by Ninputer
也许这样可以,但是……
strs.Find(delegate(string obj){return obj.StartsWith("A");}).ForEach(delegate(string obj){Console.WriteLine(obj);});
我觉得这代码已经属于“WriteOnly”了
#3楼 回复 引用 查看
2005-05-05 22:19 by Ninputer
其实我希望这段代码可以这样:
Console.WriteLine(For Each str In strs Which str.StartsWith("A"))
如果VB的开发人员听取我的意见,让VB同时具有Python般的字符串特性和Fortan般的重复输入语句的话……
#4楼 回复 引用 查看
2005-05-06 00:30 by idior
Console.WriteLine(For Each str In strs Which str.StartsWith("A"))
这个... 有点玄乎了吧.
java的风格是已有的能做就不去加入新的功能, 比如stuct delegate
C#固然可以有所创新, 但也不能走的太远对吧.
#5楼 [楼主] 回复 引用 查看
2005-05-06 10:08 by idior
另外如果这样的话.
strs.Find(delegate(string obj){return obj.StartsWith("A");}).ForEach(delegate(string obj){Console.WriteLine(obj);});
需要两次遍历, 不是吗?
#6楼 回复 引用 查看
2005-08-18 11:24 by Ninputer
发现VBF可以解决这个问题:
[VB]
strs.ForEach(Condition(Of String)(AddressOf StartsWithA, ConsoleWriteLine(Of String)()) 'StartsWithA要另写
[C#]
strs.ForEach(new Condition<string>(delegate(string obj){return obj.StartsWith("A"); }, delegate(string obj){Console.WriteLine(obj);} );
而你的方法,在C# 3.0中将变得更加优美动人(买个关子,呵呵)
#7楼 [楼主] 回复 引用 查看
2005-08-18 11:35 by idior
@Ninputer
[C#]
strs.ForEach(new Condition<string>(delegate(string obj){return obj.StartsWith("A"); }, delegate(string obj){Console.WriteLine(obj);} );
有这个方法吗?
你想说lamda表达式? 呵呵 不如写篇文章介绍一下吧. 现在有pdc的资料了吗?
#8楼 回复 引用 查看
2005-08-18 15:33 by Ninputer
目前还没到可以公开的时候吧,我可以告诉你那个特性的名字叫extension methods :).
lambda表达式也也是好东西呀。将lambda表达式和extension都用上,这个问题就有了最清晰的表达方式:
[C#]
strs.ForSpecification(|s|s.StartsWith("A"), delegate(string obj){ Console.WriteLine(obj); });
目前不知道VB9要不要加入lambda表达式,观望中……
下一篇:在Web.config中注册用户控件和自定义控件的优越性 上一篇:Petshop4.0任何引用样式表. 开放文章词条: ASP.Net2.0的集合操作 --- List? 开放文章目录: ZPYJ > 中文作品研究 > 编程知识
|
|
|
|