在我以前的一篇随笔中曾提到不要在代码中散布遍历集合的操作.而是将遍历集合的操作放入集合本身.
当时就想在.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)
}
}
{
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);
}
}
}
{
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
});
}
}
{
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方法的集合也可以使用这个辅助类来完成相应的操作.
其实还可以在辅助类中添一些方法,比如让集合中的元素相加,并返回结果, 留给大家自己实现吧.