NullReference

Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
常用的几个ForEach扩展,外送一个First方法

现在好像很多人都不太喜欢写For, ForEach, do, while这些循环了,都是用ToList.ForEach之类的。其实我也是这样,但是在.Net里,只有IList<T>有这个方法,很多时候我需要在ICollection<T>, IEnumerable<T>甚至是IEnumerable里使用同样的方式来调用,而且,自带的方法也是简单了些,只有一个遍历功能,不支持中断,没有索引……是不是很不方便呢?

 

很简单,MS不提供,我们就自己动手吧。看代码吧。

 

       /// <summary>
        /// 基本上和List<T>的ForEach方法一致。
        /// </summary>
        public static void Each<T>(this IEnumerable<T> col, Action<T> handler)
        {
            foreach (var item in col)
                handler(item);
        }

        /// <summary>
        /// 带索引的遍历方法。
        /// </summary>
        public static void Each<T>(this IEnumerable<T> col, Action<T, int> handler)
        {
            int index = 0;
            foreach (var item in col)
                handler(item, index++);
        }

        /// <summary>
        /// 可以半途中断执行的遍历方法。
        /// </summary>
        public static void Each<T>(this IEnumerable<T> col, Func<T, bool> handler)
        {
            foreach (var item in col)
                if (!handler(item)) break;
        }

        /// <summary>
        /// 可以半途中段的带索引的遍历方法。
        /// </summary>
        public static void Each<T>(this IEnumerable<T> col, Func<T, int, bool> handler)
        {
            int index = 0;
            foreach (var item in col)
                if (!handler(item, index++)) break;
        }

        #region 以下为IEnumerable<T>的非泛型实现
        public static void Each<T>(this IEnumerable col, Action<object> handler)
        {
            foreach (var item in col)
                handler(item);
        }

        public static void Each<T>(this IEnumerable col, Action<object, int> handler)
        {
            int index = 0;
            foreach (var item in col)
                handler(item, index++);
        }

        public static void Each<T>(this IEnumerable col, Func<object, bool> handler)
        {
            foreach (var item in col)
                if (!handler(item)) break;
        }

        public static void Each<T>(this IEnumerable col, Func<object, int, bool> handler)
        {
            int index = 0;
            foreach (var item in col)
                if (!handler(item, index++)) break;
        }
        #endregion

还有一个,Linq里的First很好用,但是对于动态生成的类来说,没有办法在编译之前得到IList<T>,从而都没有办法用First()方法,很不方便测试和调试,我们也扩展一个。

 

 

        /// <summary>
        /// 给非强类型的IEnumerable返回头一个元素。
        /// </summary>
        public static object First(this IEnumerable col)
        {
            foreach (var item in col)
                return item;

            throw new IndexOutOfRangeException();
        }

        /// <summary>
        /// 给非强类型的IEnumerable返回头一个强类型的元素
        /// </summary>
        public static object First<T>(this IEnumerable col)
        {
            return (T)col.First();
        }

 

 

当然这个很简单,因为我们没有事项另一个Expression的重载,不过对于测试吗,也够用了。要实现那个重载,可就不简单了,大家自己想吧!

 

-------------------------

 

总结:方法虽然简单,但是在编码的时候却很好用,而且提高很多的工作效率,何乐不为呢?

 

posted on 2010-01-11 17:16  NullReference  阅读(3200)  评论(21编辑  收藏  举报