六大设计模式原则

using DesignPatternPrinciple.DIP;
using DesignPatternPrinciple.LOP;
using DesignPatternPrinciple.SRP;
using System;
using DesignPatternPrinciple.Homeworks;
using System.Collections.Generic;
using System.Linq;

namespace DesignPatternPrinciple
{
    class Program
    {
        static void Main(string[] args)
        {
            //1.单一职责原则(Single Responsibility Principle)
            //2.里氏替换原则(Liskov Substitution Principle)
            //3.依赖倒置原则(Dependence Invention Principle)
            //4.接口隔离原则(Interface Segregation Principle)
            //5.迪米特法则(Law Of Demeter)//最少知道原则
            //6.开闭原则(Open Close Principle)

            //SRPShow.show();
            //LOPShow.Show();
            //DIPShow.show();

            //子类静态变量>子类静态构造函数>子类非静态变量>父类静态变量>父类静态构造函数>父类非静态变量>父类无参构造函数>子类无参构造函数;
            //Father father0 = new Father();//静态构造函数先执行,其次无参构造函数
            //Father father1 = new Father(1);//静态构造函数先执行,其次带参构造函数  但是静态构造函数在上面已经执行一次,不会再执行了

            //Children children = new Children();
            //Children children1 = new Children(1);
            Console.WriteLine("---------------");
            Father father2 = new Children();
            Father father3 = new Children(1);
            father2.show();//如果子类是override,那么调用的是子类覆写的方法;如果子类用new,那么调用的是父类的方法
            //为什么这么些,依赖倒置  实现多态
            int loc = 0;

            #region 作业
            var objEast = (EastVentriloquism)Homework.SimpleFactory(VentriloquismEnum.East);
            Homework.Show(objEast);
            var objWest = (WestVentriloquism)Homework.SimpleFactory(VentriloquismEnum.West);
            Homework.Show(objWest);
            var objSouth = (SouthernVentriloquism)Homework.SimpleFactory(VentriloquismEnum.South);
            Homework.Show(objSouth);
            var objNorth = (NorthVentriloquism)Homework.SimpleFactory(VentriloquismEnum.North);
            Homework.Show(objNorth);

            Homework.UniqueSkill(objEast.UniqueSkill);
            Homework.UniqueSkill(objWest.UniqueSkill);
            Homework.UniqueSkill(objSouth.UniqueSkill);
            Homework.UniqueSkill(objNorth.UniqueSkill);

            Console.WriteLine("=================================事件======================");
            objSouth.eventhandler += (sender, args) => Console.WriteLine("夫起大呼");
            objSouth.eventhandler += (sender, args) => Console.WriteLine("妇亦起大呼");
            objSouth.eventhandler += (sender, args) => Console.WriteLine("两儿齐哭");
            objSouth.eventhandler += (sender, args) => Console.WriteLine("俄而百千人大呼");
            objSouth.eventhandler += (sender, args) => Console.WriteLine("百千儿哭");
            objSouth.eventhandler += (sender, args) => Console.WriteLine("百千犬吠");

            objNorth.eventhandler += new Audience().HusbandShout;
            objNorth.eventhandler += new Audience().WifeShout;
            objNorth.eventhandler += new Audience().SonShout;
            objNorth.eventhandler += new Audience().MansShout;
            objNorth.eventhandler += new Audience().SonsShout;
            objNorth.eventhandler += new Audience().DogsShout;

            objWest.eventhandler += (sender, args) =>
            {
                var fireargs = (FireEventArgs)args;
                var westven = (WestVentriloquism)sender;
                Console.WriteLine($"夫起大呼,现在温度:{fireargs?.temperature},{westven.Name}燃点:{westven.IgnitionPoint}");
            };
            objWest.eventhandler += (sender, args) =>
            {
                var fireargs = (FireEventArgs)args;
                var westven = (WestVentriloquism)sender;
                Console.WriteLine($"妇亦起大呼,现在温度:{fireargs?.temperature},{westven.Name}燃点:{westven.IgnitionPoint}");
            };

            objEast.eventhandler += new EastAudience().HusbandShout;
            objEast.eventhandler += new EastAudience().WifeShout;

            objSouth.SetTemperature(1200);
            objNorth.SetTemperature(1200);
            objWest.SetTemperature(1200);
            objEast.SetTemperature(1200);

            MiddleVentriloquism middleVentriloquism = new MiddleVentriloquism();
            middleVentriloquism.StartEvent += () => Console.WriteLine("中派表演开始事件");
            middleVentriloquism.ClimaxEvent += () => Console.WriteLine("中派表演高潮事件");
            middleVentriloquism.EndEvent += () => Console.WriteLine("中派表演结束事件");

            middleVentriloquism.Show();

            IEnumerable<int> vs = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 8, 8 };
            var rst = vs.GetByRandom(5);
            #endregion
        }
    }
    #region this和base关键字区别
    //this关键字代表当前对象,通过this关键字可以访问当前对象的成员。(当前对象的成员:自己本身的成员+从父类继承过来的所有的成员。)
    //this关键字可以访问:本类的所有成员和父类的非私有成员。父类的私有成员确实存在,但是就是访问不到。
    // this关键字仍然代表的是对象,通过它可以点出对象中的除了父类的私有成员以外的所有成员。
    // this关键字只能用在实例方法中。
    //作用:
    //1)代表当前对象。在实例方法中使用this关键字就代表当前对象。通过this关键字可以点出本类的所有成员和父类的非私有成员。
    //2)调用本类的其他的构造函数。在构造函数的后面的this代表调用本类的其他的构造函数。

    //显示的访问父类的非私有成员。可以访问子类对象中的父类的非私有成员。base不代表父类对象。因为压根就没有父类对象。通过它可以访问到父类的非私有成员。
    //通过this关键字访问当前对象的成员的时候:先找子类本身有没有这个成员,如果没有再找是否有从父类继承过来的。base关键字 直接就找父类中的成员。我们发现,base可以点出来的成员,通过this都可以点出来访问。
    //建议:如果我们访问的确实是从父类继承过来的,那么建议用base关键字访问,这样方便代码的阅读和提高效率。只有在访问的成员确实是子类独有的,那么我们才用this关键字。
    // 作用:
    //1)在实例方法中,通过base关键字可以显示的访问子类对象中的非私有的父类成员。
    // 2)调用父类的构造函数。在子类的构造函数的后面的base代表调用父类的构造函数。
    #endregion

    #region protected关键字
    //protected 给基类和子类用,实例不能用,除非实例存在于自己本类中
    //可以通过this 访问自己的project和 base访问父类的project

    //为了给派生类中用,如果不给派生类用,直接private


    public class A
    {
        public int a = 1;
        protected int b = 2;
    }

    public class B : A
    {
        public int c = 0;
        //public void show1()
        //{
        //    A a = new A();
        //    this.a = a.a;
        //    this.c = a.b;//报错
        //    Console.WriteLine($"a:{a};b:{b}");
        //}

        public void show2()
        {
            B b = new B();
            this.c = b.b;//在自己的类内部,是可以实例化自己,然后访问project
            Console.WriteLine($"this.b:{this.b};b:{base.b}");//类内部,也可以通过base访问父类的project
        }
    }

    public class C
    {
        //public void show3()
        //{
        //    B b = new B();
        //    A a = new A();
        //    Console.WriteLine($"{a.b}{b.b}");//报错,类外部实例就用不了了
        //}
    }
    #endregion

    #region 构造函数执行顺序
    public class Father
    {
        public Father()
        {
            Console.WriteLine("Father无参构造函数");
        }

        static Father()
        {
            Console.WriteLine("Father静态无参构造函数");
        }

        public Father(int i)
        {
            Console.WriteLine("Father带参构造函数");
        }

        public virtual void show()
        {
            Console.WriteLine("Father  show");
        }
    }

    public class Children : Father
    {
        public Children() : base()
        {
            Console.WriteLine("Children无参构造函数");
        }

        static Children()
        {
            Console.WriteLine("Children静态无参构造函数");
        }
        public Children(int i) : base(i)
        {
            Console.WriteLine("Children带参构造函数");
        }
        public override void show()
        {
            Console.WriteLine("Children  show");
        }
        //public new void show()
        //{
        //    Console.WriteLine("Children  show");
        //}
    }
    #region 验证单例
    public sealed class Singleton
    {
        /*单例四要素:
         1.私有静态属性,类型是本对象
         2.私有构造函数
         3.静态构造函数,实例化本对象赋值给私有静态属性
         4.提供给外部的方法,返回私有静态属性
         */
        //反射会破环单例--反射可以调用私有构造函数
        public string Name { set; get; }

        //private static Singleton singleton = new Singleton();

        private static Singleton singleton = null;
        static Singleton()
        {
            singleton = new Singleton();
        }

        private Singleton()
        {
            Console.WriteLine("私有构造函数被创建");
        }

        public static Singleton GetSingleton()
        {
            return singleton;
        }
    }
    #endregion
    #endregion

    //core中接口也可以实现成员
    public interface AA
    {
        public void show()
        {
            Console.WriteLine("Interface AA");
        }
    }

    public class AAA : AA
    {

    }


}

1.单一职责

using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatternPrinciple.SRP
{
    //单一职责原则:类T负责两个不同的职责,P1和P2。当由于职责P1需求发生改变而修改T时,有可能导致原本正常的P2职责功能发生故障
    //一个类只干一件事,职责清晰
    //拆分父类和子类,每个类很简单,稳定
    //但是代码量增大,理解成本变高

    //扩展:方法层面的单一职责;类库层面/项目层面的单一职责;系统级别的单一功能
    public class SRPShow
    {
        public static void show()
        {
            Animal animal = new Brid();
            animal.Breath();
        }
    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatternPrinciple.SRP
{
    public abstract class Animal
    {
        protected string Name { set; get; }

        public Animal(string name)
        {
            this.Name = name;
        }

        父类中出现了好几个子类该有的动作,而且不止一个部分出现,这个时候应该拆分
        父类变成abstract 子类
        //protected void Breath()
        //{
        //    if (this.Name == "鸟")
        //        Console.WriteLine("呼吸空气");
        //    if (this.Name == "鱼")
        //        Console.WriteLine("呼吸水");
        //    if (this.Name == "蚯蚓")
        //        Console.WriteLine("呼吸泥土");
        //}

        public abstract void Breath();
        public abstract void Motion();
        //protected void Motion()
        //{
        //    if (this.Name == "鸟")
        //        Console.WriteLine("flying");
        //    if (this.Name == "鱼")
        //        Console.WriteLine("swimming");
        //    if (this.Name == "蚯蚓")
        //        Console.WriteLine("crawling");
        //}
    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatternPrinciple.SRP
{
    public class Brid : Animal
    {
        public Brid() : base("鸟")
        {

        }
        public override void Breath()
        {
            Console.WriteLine("呼吸空气");
        }
        public override void Motion()
        {
            Console.WriteLine("呼吸空气");
        }
    }
}

2.里氏替换

using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatternPrinciple.LSP
{
    //里氏替换原则:任何使用基类的地方,都可以透明的使用子类
    //继承:子类拥有父类的一切属性和行为,任何出现父类的地方,都可以用子类来代替
    //继承+透明(安全,不会出现行为的不一致)

    /*1.父类有的,子类必须有,否则应该断掉继承;(再来一个祖父类,只包含必须有的东西)
     *2.子类可以有自己的属性和行为,所以在子类出现的地方,父类不一定能代替
     *3.避免重写(不new),因为如果此时有人不知道用var声明一个子类,在他并不知道父子类内容的情况下会调不到父类的方法,走的是子类的方法;
     * 如果父类的方法属性有被子类改动的可能性,用abstract或者virtual,原因同上
     *4.重写或实现父类的方法是,入参形参要比父类的范围大,返回值要比父类的小
     */
    public class LSPShow
    {

    }

    public class People
    {
        public int Id { set; get; }
        public string Name { set; get; }

        public virtual void Tradition()
        {
            Console.WriteLine("传统美德");
        }
    }

    public class Chanese: People
    {
        public override void Tradition()
        {
            Console.WriteLine("仁义礼智信");
        }
    }

    public class Japanese : People
    {
        //这么写不符合里氏替换原则,如果子类不包含父类的方法,应该断掉继承
        //public virtual void Tradition()
        //{
        //    throw new Exception();
        //}
    }
}

3.迪米特(最少知道原则)

using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatternPrinciple.LOP
{
    /*迪米特法则(最少知道原则):一个对象应该对其他对象保持最少的了解
     * 只与直接的朋友通讯
     * 
     * 背景:面向对象语言-----万物皆对象-----要产生功能------类与类要交互-----这就耦合了
     *  类与类之间的关系:
     *  纵向:继承≈实现
     *  横向:聚合>组合>关联>依赖(出现在方法内部的类就构成依赖)
     * 
     * 作用:降低类与类之间的耦合
     *  只和直接的朋友通讯,那就要降低依赖,就是减少在方法内部的类型(基类BCL除外)
     * 
     * 但是会增加额外的成本
     * 
     * 应用:
     *  工作中会构建中间层/中介
     *  门面模式  中介者模式  分层模式都属于这种
     *      上层UI--->下层子系统(订单/支付/仓储/物流)这个架构给UI和子系统中间加一层门面,UI只依赖门面,门面去交互子系统
     *  三层架构:UI--BLL(业务逻辑层)--DAL(数据交互层)
     *  
     * 要遵循的话代码风格:
     *  避免方法内部依赖
     *  降低访问修饰符权限
     *  private
     *  protect
     *  internal
     *  protect internal(子类或者同类库)
     *  
     * 迪米特法则:依赖别人更少,别人了解更少 --->逐渐自闭
    */
    public class LOPShow
    {
        public static void Show()
        {
            School school = new School()
            {
                ID = 1,
                SchoolName = "吃法大学",
                classes = new List<Class>()
                {
                    new Class ()
                    { 
                        ID = 1,
                        ClassName = "一班",
                        students = new List<Student> ()
                        { 
                            new Student()
                            { 
                                ID = 1,
                                StudentName = "小王",
                            },
                            new Student()
                            { 
                                ID = 2,
                                StudentName = "小高"
                            }
                        }
                    }
                }
            };
            school.Manage();
            school.Manage1();
        }
    }

    public class School
    {
        public int ID { set; get; }
        public string SchoolName { set; get; }
        public List<Class> classes { set; get; }

        //这个方法中依赖班级Class和学生Student两个类型,耦合太重,按照迪米特法则,学校直接交互的应该是班级,学生应该放到班级中去交互,写方法Manage1(),学生的管理放到班级中去
        public void Manage()
        {
            foreach (var clas in this.classes)
            {
                Console.WriteLine($"{this.GetType().Name}管理{clas.ClassName}");
                foreach (var stu in clas.students)
                {
                    Console.WriteLine($"{clas.GetType().Name}管理{stu.StudentName}");
                }
            }
        }

        //这个方法遵循迪米特法则,学校类只与班级通讯
        public void Manage1()
        {
            foreach (var clas in this.classes)
            {
                Console.WriteLine($"{this.GetType().Name}管理{clas.ClassName}");
                clas.Manage();
            }
        }
    }

    public class Class
    {
        public int ID { set; get; }
        public string ClassName { set; get; }
        public List<Student> students { set; get; }
        public void Manage()
        {
            foreach (var stu in this.students)
            {
                Console.WriteLine($"{this.GetType().Name}管理{stu.StudentName}");
            }
        }
    }

    public class Student
    {
        public int ID { set; get; }
        public string StudentName { set; get; }
        //public 
    }
}

4.依赖倒置

using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatternPrinciple.DIP
{
    /* 依赖倒置原则:高层模块不应该依赖低层模块,二者应该通过抽象来依赖
     * 依赖抽象,而不应该依赖细节
     * 
     * 抽象指 接口/抽象类(通常情况下应该写接口,除非是有些通用功能可以在抽象类中实现;抽象类描述是什么,接口描述能干什么)
     * 细节指 普通类
     * 
     * 面向抽象编程:尽量的使用抽象,80%以上的设计模式都和抽象有关
     *  属性/字段/方法参数、返回值  尽量都是抽象
    */
    public class DIPShow
    {
        public static void show()
        {
            Student student = new Student()
            { 
                Id = 1,
                Name = "小王"
            };
            {
                MI mi = new MI();
                student.Use(mi);
            }
            {
                IPhone iphone = new IPhone();
                student.Use(iphone);
            }

        }
    }

    public abstract class AbstractPhone
    {
        public int ID { set; get; }
        public string Branch { set; get; }
        public abstract void Call();
        public abstract void Text();
    }

    public class MI : AbstractPhone
    {
        public override void Call()
        {
            Console.WriteLine($"Use {this.GetType().Name} call");
        }
        public override void Text()
        {
            Console.WriteLine($"Use {this.GetType().Name} text");
        }
    }

    public class IPhone : AbstractPhone
    {
        public override void Call()
        {
            Console.WriteLine($"Use {this.GetType().Name} call");
        }
        public override void Text()
        {
            Console.WriteLine($"Use {this.GetType().Name} text");
        }
    }

    public class Student
    {
        public int Id { set; get; }
        public string Name { set; get; }

        //入参改为手机的抽象,这样就不用针对不同的手机写不同的方法
        //当然可以用泛型+父类约束来实现,但这样其实就等于入参的类型改为抽象
        
        //面向抽象的好处:除了满足不同的入参,还支持扩展,比如再来一个新类型的手机,只要它继承手机抽象类,上层的类不用变化,比如学生类中的Use方法不用动
        //如果依赖细节,底层有变化了,变化会传递到上层
        //依赖抽象,只要抽象层稳定,底层的变化不会传递到上层,这样就能支持层内部的扩展,比如新加手机,这样的程序架构就是稳定的

        //但是依赖抽象支持的是通用功能,不支持某个底层的特殊功能,比如现在小米手机的Use除了打电话发短信还增加手环功能,这样就通用不了了,要么该抽象层,要么小米的Use要独立出来

        //依赖倒置原则(理论基础)-------Ioc控制反转(原理的实践封装)(上层把实例化下层的步骤交给第三方)-------DI依赖注入(实现Ioc的手段)

        public void Use(AbstractPhone phone)
        {
            Console.WriteLine($"这是 {this.Name} 的手机");
            phone.Call();
            phone.Text();
        }
    }
}

5.接口隔离

using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatternPrinciple.ISP
{
    //接口隔离原则:客户端不应该依赖它不需要的接口
    //一个类对另一个类的依赖应该建立在最小的接口上

    //接口定义应该遵循:
        //1.不能是大而全的接口,因为这样会让子类实现一些本身不需要的功能
        //2.也不能定义的太碎,不能一个方法一个接口
        //3.应该按照功能的密不可分性定义接口,当然,随着业务的发展,接口也可能会调整,所以在定义抽象时应该预留提前量
        //4.接口合并:提高接口的内聚性,在接口内部,原本实际情况是一体的方法没必要拆开,都暴露出来,比如导航功能,定位/搜索/导航 是一体的,没必要分为三个方法暴露给子类

    public class ISPShow
    {
    }
}

6.开闭

using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatternPrinciple.OCP
{
    //开闭原则:对扩展开放,对修改关闭
    //  修改:修改现有代码(修改类)
    //  扩展:增加代码(类)
    //开闭原则是最终追求
    public class OCPShow
    {
    }
}

作业:

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace DesignPatternPrinciple.Homeworks
{
    public class Homework
    {
        public static VentriloquismPerform SimpleFactory(VentriloquismEnum @enum)
        {
            switch (@enum)
            {
                case VentriloquismEnum.East: return new EastVentriloquism();
                case VentriloquismEnum.West: return new WestVentriloquism();
                case VentriloquismEnum.South: return new SouthernVentriloquism();
                case VentriloquismEnum.North: return new NorthVentriloquism();
                default: return null;
            }
        }

        public static void Show<T>(T t) where T : VentriloquismPerform, ICharge
        {
            Type type = t.GetType();
            object obj = Activator.CreateInstance(type);
            foreach (PropertyInfo property in type.GetProperties())
            {
                Console.WriteLine($"{property.Name}-{property.GetValue(obj)}");
            }
            t.Start();
            t.Prologue();
            t.DogsBark();
            t.HumanShout();
            t.WindSound();
            t.Conclusion();
            t.Charge();
        }

        public static void UniqueSkill(Action action)
        {
            Console.WriteLine("绝活马上开始");
            action.Invoke();
            Console.WriteLine("绝活表演结束,大家鼓掌");

        }
    }

    public enum VentriloquismEnum
    {
        East,
        West,
        South,
        North,
    }
}

抽象父类

using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatternPrinciple.Homeworks
{
    public abstract class VentriloquismPerform
    {
        public string Human { set; get; }
        public string Table { set; get; }
        public string Ruler { set; get; }
        public string Chair { set; get; }
        public string Fan { set; get; }

        public void Start()
        {
            Console.WriteLine("表演开始了");
        }

        public abstract void DogsBark();
        public abstract void HumanShout();
        public abstract void WindSound();

        /// <summary>
        /// 开场白
        /// </summary>
        public virtual void Prologue()
        {
            Console.WriteLine("开始了");
        }
        /// <summary>
        /// 结束语
        /// </summary>
        public virtual void Conclusion()
        {
            Console.WriteLine("结束了");
        }

        public event EventHandler eventhandler;

        /// <summary>
        /// 燃点
        /// </summary>
        public virtual int IgnitionPoint { get; } = 400;

        /// <summary>
        /// 设置温度
        /// </summary>
        /// <param name="tem"></param>
        public void SetTemperature(int tem)
        {
            if (tem > IgnitionPoint)
            {
                Console.WriteLine("火起");
                eventhandler?.Invoke(this, new FireEventArgs
                { temperature = tem });
            }
        }
        //事件的触发必须在自己的类中,触发的条件和触发的流程一般写死了
        //两个不写死小套路:
        //1.把触发条件封装一个虚方法,可以被子类重写,这样条件就变得灵活
        //2.把事件执行动作封装出去;子类想什么时候执行事件就什么时候执行,流程就可以扩展了

        //这个是1的方法;子类可以根据自己的需要重写触发逻辑
        protected virtual bool isOn(int tem)
        {
            return tem > IgnitionPoint;
        }

        //这个是2的方法;子类可以任何地方调用事件
        protected void EventInvoke(FireEventArgs fireEventArgs)
        {
            eventhandler?.Invoke(this, fireEventArgs);
        }
    }

    //事件参数类
    public class FireEventArgs : EventArgs
    {
        public int temperature { set; get; }
    }
}

接口

using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatternPrinciple.Homeworks
{
    public interface ICharge
    {
        public void Charge();
    }
}

东南西北中派口技类

using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatternPrinciple.Homeworks
{
    public class EastVentriloquism : VentriloquismPerform, ICharge
    {
        private string _name = "东派";
        
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        public void UniqueSkill()
        {
            Console.WriteLine($"{_name}绝活");
        }



        public override void DogsBark()
        {
            Console.WriteLine($"{_name}犬吠");
        }
        public override void HumanShout()
        {
            Console.WriteLine($"{_name}人叫");
        }
        public override void WindSound()
        {
            Console.WriteLine($"{_name}风声");
        }

        public void Charge()
        {
            Console.WriteLine($"{_name}收费");
        }
       
    }

    public class EastAudience
    {
        public void HusbandShout(object send, EventArgs eventArgs)
        {
            var fireargs = (FireEventArgs)eventArgs;
            var westven = (EastVentriloquism)send;
            Console.WriteLine($"夫起大呼,现在温度:{fireargs?.temperature},{westven?.Name}燃点:{westven?.IgnitionPoint}");
        }
        public void WifeShout(object send, EventArgs eventArgs)
        {
            var fireargs = (FireEventArgs)eventArgs;
            var westven = (EastVentriloquism)send;
            Console.WriteLine($"妇亦起大呼,现在温度:{fireargs?.temperature},{westven?.Name}燃点:{westven?.IgnitionPoint}");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatternPrinciple.Homeworks
{
    public class SouthernVentriloquism : VentriloquismPerform, ICharge
    {
        private string _name = "南派";

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        public void UniqueSkill()
        {
            Console.WriteLine($"{_name}绝活");
        }

        public override void Prologue()
        {
            Console.WriteLine($"{_name}开场白");
        }

        public override void DogsBark()
        {
            Console.WriteLine($"{_name}犬吠");
        }
        public override void HumanShout()
        {
            Console.WriteLine($"{_name}人叫");
        }
        public override void WindSound()
        {
            Console.WriteLine($"{_name}风声");
        }

        public void Charge()
        {
            Console.WriteLine($"{_name}收费");
        }

        public override int IgnitionPoint { get; } = 800;
    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatternPrinciple.Homeworks
{
    public class WestVentriloquism : VentriloquismPerform, ICharge
    {
        private string _name = "西派";

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        public void UniqueSkill()
        {
            Console.WriteLine($"{_name}绝活");
        }

        public override void Prologue()
        {
            Console.WriteLine($"{_name}开场白");
        }

        public override void Conclusion()
        {
            Console.WriteLine($"{_name}结束语");
        }

        public override void DogsBark()
        {
            Console.WriteLine($"{_name}犬吠");
        }
        public override void HumanShout()
        {
            Console.WriteLine($"{_name}人叫");
        }
        public override void WindSound()
        {
            Console.WriteLine($"{_name}风声");
        }

        public void Charge()
        {
            Console.WriteLine($"{_name}收费");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatternPrinciple.Homeworks
{
    public class NorthVentriloquism : VentriloquismPerform, ICharge
    {
        private string _name = "北派";

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        public void UniqueSkill()
        {
            Console.WriteLine($"{_name}绝活");
        }

        public override void Conclusion()
        {
            Console.WriteLine($"{_name}结束语");
        }

        public override void DogsBark()
        {
            Console.WriteLine($"{_name}犬吠");
        }
        public override void HumanShout()
        {
            Console.WriteLine($"{_name}人叫");
        }
        public override void WindSound()
        {
            Console.WriteLine($"{_name}风声");
        }

        public void Charge()
        {
            Console.WriteLine($"{_name}收费");
        }

        public override int IgnitionPoint { get; } = 800;
    }

    public class Audience
    {
        public void HusbandShout(object send, EventArgs eventArgs)
        {
            Console.WriteLine("夫起大呼");
        }
        public void WifeShout(object send, EventArgs eventArgs)
        {
            Console.WriteLine("妇亦起大呼");
        }
        public void SonShout(object send, EventArgs eventArgs)
        {
            Console.WriteLine("两儿齐哭");
        }
        public void MansShout(object send, EventArgs eventArgs)
        {
            Console.WriteLine("俄而百千人大呼");
        }
        public void SonsShout(object send, EventArgs eventArgs)
        {
            Console.WriteLine("百千儿哭");
        }
        public void DogsShout(object send, EventArgs eventArgs)
        {
            Console.WriteLine("百千犬吠");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatternPrinciple.Homeworks
{
    public class MiddleVentriloquism : VentriloquismPerform, ICharge
    {
        private string _name = "中派";
        public override void DogsBark()
        {
            Console.WriteLine($"{_name}犬吠");
        }
        public override void HumanShout()
        {
            Console.WriteLine($"{_name}人叫");
        }
        public override void WindSound()
        {
            Console.WriteLine($"{_name}风声");
        }
        public void Charge()
        {
            Console.WriteLine($"{_name}收费");
        }
        public void UniqueSkill()
        {
            Console.WriteLine($"{_name}绝活");
        }

        public event Action StartEvent;

        public event Action ClimaxEvent;

        public event Action EndEvent;

        public void Show()
        {
            base.Start();
            base.Prologue();
            this.StartEvent?.Invoke();
            this.DogsBark();
            this.HumanShout();
            this.WindSound();
            this.UniqueSkill();
            this.ClimaxEvent?.Invoke();
            base.Conclusion();
            this.Charge();
            this.EndEvent?.Invoke();
        }
    }
}

 

封装一个随机取列表指定个数的Linq方法

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DesignPatternPrinciple.Homeworks
{
    public static class LinqExtend
    {
        public static IEnumerable<T> GetByRandom<T>(this IEnumerable<T> ts, int count)
        {
            if (ts == null || ts.Count() <= count)
                return null;
            else
            {
                IEnumerable<T> rst = ts.OrderBy(t => Guid.NewGuid());
                return rst.Take(count);
            }
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值