c#扩展方法(this) 迭代器

学生类:

 /// <summary>
    /// 学生实体
    /// </summary>
    public class Student
    {
        public int Id { get; set; }
        public int ClassId { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }

        public void Study()
        {
            Console.WriteLine("{0} {1}跟着Richard老师学习.net高级开发", this.Id, this.Name);
        }

        public void StudyHard()
        {
            Console.WriteLine("{0} {1}跟着Richard老师努力学习.net高级开发", this.Id, this.Name);
        }

    }

调用:

                  Student student = new Student()
                    {
                        Id = 1,
                        Name = "Mr.zhang",
                        Age = 25,
                        ClassId = 2
                    };
                    student.Study();

之后如果在学生类再加一个方法,正常的情况下是直接在学生类中做修改,但是如果为了遵循开闭原则的话可以做一个扩展方法:

    public static class ExtendMethod
    {  /// <summary>
        /// 扩展方法:添加一个第三方静态类,把当前需要扩展的类作为参数添加方法,在第一个参数前加一个this
        /// </summary>
        /// <param name="student"></param>
        public static void StudyPractise(this Student student)
        {
            Console.WriteLine("{0} {1}跟着Richard老师学习基础班!", student.Id, student.Name);
        } 
    }

调用:

   student.StudyPractise(); //扩展方法;看起来跟实例方法调用方式一样

还可以对object的扩展方法:

        /// <summary>
        /// 自定义的扩展方法
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ObjTostringCustom(this object obj)// 默认参数
        {
            if (obj is Guid)
            {
                return obj.ToString();
            }
            ///.....
            else
            {
                return obj.ToString();
            }
        }

但是需要注意的是,使用object类型容易污染,因为没有类型限制,只要是继承于object的类型都能调用。

对泛型的扩展示例

      public static string GenericExtend<T>(this T t)// 默认参数
        {
            if (t is Guid)
            {
                return t.ToString();
            }
            ///.....
            else
            {
                return t.ToString();
            }
        }

迭代器

通过yield+IEnumerable能够实现按需获取,延迟加载。

看下面的代码:

        /// <summary>
        /// 迭代器 (迭代器模式)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="resource"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static IEnumerable<T> JerryWhereIterator<T>(this IEnumerable<T> resource, Func<T, bool> func)
        {
            foreach (var item in resource)
            {
                Console.WriteLine("开始检查");
                Thread.Sleep(300);
                if (func.Invoke(item))
                {
                    yield return item; // yield 和Enumerabl 是配合使用,按需获取/延时加载
                }
            }

        }

调用:

                var list3 = studentList.JerryWhereIterator(a => a.Age < 30);
                foreach (var item in list3)
                {
                    Console.WriteLine(item.Name);
                }

在调用的时候,只有在foreach遍历的时候才会真正的调用JerryWhereIterator内部的代码,每一次遍历都会走一次下面的代码:

         foreach (var item in resource)
            {
                Console.WriteLine("开始检查");
                Thread.Sleep(300);
                if (func.Invoke(item))
                {
                    yield return item; // yield 和Enumerabl 是配合使用,按需获取/延时加载
                }
            }

只要有一条符合,就返回。如果是普通的那种List,就是需要全部处理完才会返回。

原文地址:https://www.cnblogs.com/anjingdian/p/15369381.html