安静且高效一点就好4

2020/10/29


前言

本文主要对泛型做一个概述,对委托和事件的一个概述


提示:以下是本篇文章正文内容,下面案例可供参考

一、泛型

1.泛型的定义:声明类和方法时一般都需要定义是什么类,class Brid ,Class Food… 声明泛型类和方法时只需要传入类型的地方用 ,有点类似于占位符的作用,用的时候传入具体的类型。当针对不同类型具有相同行为的时候,也就是泛型发挥作用的时候。
自己对泛型的理解为:假设我开一个小卖部,要买苹果就得拿苹果篮子来装(声明苹果类),卖书的话就得拿书来装(声明书类),这样势必会造成类和成员的膨胀,为了解决这样的问题那么引入了泛型。
2.泛型的优点:
a.使用泛型类、方法,我们可以极大提高代码的重用性,不需要对类型不同代码相同(仅类型参数不同)的代码写多次。
b .创建泛型类,可在编译时创建类型安全的集合
c.避免装箱和拆箱操作降低性能,在大型集合中装箱和拆箱的影响非常大,
下面的代码主要是针对泛型使用的好处,泛型类,泛型接口,泛型委托,泛型方法的了解:
代码如下(示例):

namespace fanxing
{
    class Program
    {
        static void Main(string[] args)
        {



            #region 泛型委托,加一句Lambda表达式
            --->Action泛型委托,他是给没有返回值用的。
            Action<string> a1 = Say;
            a1.Invoke("Timothy");
            Action<int> a2 = Mul;
            a2(2);

            Func<int, int, int> func1 = Add;
            Console.WriteLine(func1(100, 200));

            Func<double, double, double> func2 = Add;
            Console.WriteLine(func2(100.1,200.2));

            Func<int, int, int> func3 = (int a, int b) => { return a + b; };
            Console.WriteLine(func3.Invoke(200, 200));

            #endregion

            #region 写一点泛型集合常见的列子
            IDictionary<int, string> dict = new Dictionary<int, string>();
            dict[1] = "Timothy";
            dict[2] = "Michael";
            Console.WriteLine($"Student #1 is {dict[1]}");
            Console.WriteLine($"Student #2 is {dict[2]}");


            IList<int> list = new List<int>();
            for (int i = 0; i < 100; i++)
            {
                list.Add(i);
            }


            foreach (var item in list)
            {
                Console.WriteLine(item);
            }

            #endregion

            --->一个类实现的是泛型接口,那么这个类也是泛型类。
            Apple apple = new Apple() { Color = "Red" };
            Book book = new Book() { Name = "New Book" };
            Student<int> student = new Student<int>();
            student.ID = 101;
            student.Name = "Timothy";

            Student student1 = new Student();
            student1.ID = 100;
            Console.WriteLine(student.ID);

            --->好处是这样既不会产生类型膨胀,也不会产生成员膨胀
            Box<Apple> box1 = new Box<Apple>() { Cargo = apple };
            Box<Book> box2 = new Box<Book>() { Cargo = book };

            Console.WriteLine(box1.Cargo.Color);
            Console.WriteLine(box2.Cargo.Name);

            --->下面这种方式,针对每一个物品都需要一个盒子来装,所以这样会导致类型膨胀,而采用object类型来做的话,就调用不到里面的属性了,所以要采用泛型来做
            --->如果是采用泛型来做,这样避免了成员膨胀和类膨胀,而且泛型具有类型推断功能(这就是泛型的具体作用)

            BookBox bookBox = new BookBox() { BookCargo = book };
            Console.WriteLine(bookBox.BookCargo.Name);

            AppleBox appleBox = new AppleBox() { Cargo = apple };
            Console.WriteLine(appleBox.Cargo.Color);
            Console.ReadKey();
        }

        #region 为泛型委托提供的方法
        static void Say(string str)
        {
            Console.WriteLine($"Hello,{str}!");
        }

        static void Mul(int x)
        {
            Console.WriteLine(x * 100);
        }


        static int Add(int a, int b)
        {
            return a + b;
        }
        static double Add(double a, double b)
        {
            return a + b;
        }
        #endregion
    }
    
    #region 泛型接口接口中的两种泛型 1.一种是类继承与接口但是但是不特化出具体的数据类型(实例化泛型类的时候才给一定的类型)
        --->2.二种是直接特化接口,就直接特化出具体的数据类型
    interface IUnique<TId>
    {
        TId ID { get; set; }
    }
    --->特化接口,就是继承就给实际类型---->IUnique<ulong>
    class Student : IUnique<ulong>
    {
        public ulong ID { get; set; }

    }

    interface IUnique1<TId>
    {
        TId ID { get; set; }
    }

    --->要继承与一个泛型接口那么这个类也要变为泛型类才行,泛型类中可以包含非泛型成员,因为实现这个接口的时候,没有指定这个接口的中id的类型
    ---> 就是等着类实例化才去给定这个属性类型
    class Student<TId> : IUnique<TId>
    {
        public TId ID { get; set; }
        public string Name { get; set; }
    }
    #endregion

    #region 对泛型的了解提供的代码
    class Apple
    {
        private string color;
        public string Color
        {
            get { return color; }
            set { color = value; }
        }
    }
    class Book
    {
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }



    --->采用泛型来做。
    class Box<T>
    {
        public T Cargo { get; set; }
    }




   --->这个类拿来装苹果
    class AppleBox
    {
        private Apple cargo;
        public Apple Cargo
        {
            get { return cargo; }
            set { cargo = value; }
        }
    }

    --->这个类拿来装书
    class BookBox
    {
        private Book bookCargo;
        public Book BookCargo
        {
            get { return bookCargo; }
            set { bookCargo = value; }
        }
    }
    #endregion
}

二、委托

1.委托概念及其语法

1.委托定义:委托就是一个函数指针,他可以指向一个传进来的函数地址,就是将一个函数作为参数传递给另一个函数
2.关于委托的特性以及规则,匿名函数与Lambda初次了解:
a.传递的函数一定跟委托具有相同的签名,及其返回值
b.函数可以直接赋值给委托
c.匿名函数:如果函数只用一次,不需要再别的地方被重复的调用么可以写成匿名函数
d.Lambda表达式,匿名函数的简化版
e.c#只有Action和Func委托,其中Action是没有返回值的,Func有返回值
代码如下(示例):

class Program
    {
        static void Main(string[] args)
        {
            //委托:就是将一个函数作为参数传递给另一个函数
            
            string[] names = {"abcDDEd","dasdaQWEQ", "dasdaQWEQ", "dasdaQWEQ" };

            //三个需求:
            //第一个需求:把数组中每个元素都变成小写
            //第二个需求:把数组中每个元素都变成大写
            //第三个需求:把数组中每个元素两遍再加上一对双引号
            ProcessStr(names,SToUpper);//这里其实就是把函数传进去了,但是传进去的函数必须要是委托一样的签名和返回值

            //传递的函数一定跟委托具有相同的签名
            //结论:函数可以直接赋值给委托
            //但是其实他在运行时,就是在调用传进去的函数,其实就是委托指向了传进去的那个函数,真的在做事的就是那个函数
            //DelSayHi del = SayHiChinese; //new DelSayHi(SayHiChinese);
            //del("张三");

            //匿名函数:如果函数只用一次,不需要再别的地方被重复的调用么可以写成匿名函数
            //SayHi("张三",SayHiEnglish);
            SayHi("张三",
                delegate(string name)
                {
                    Console.WriteLine("你好{0}~!!!!!!!",name);
                }
                );

            //Lambda表达式,匿名函数的简化版
            SayHi("李四", name => { Console.WriteLine("吃了吗?"+name); });

            Console.ReadKey();

        }
        public static void ProcessStr(string[] names, DelProStr del)
        {
            for (int i = 0; i < names.Length; i++)
            {
                names[i] = del(names[i]);
            }
        }

        static void SayHi(string name, DelSayHi del)
        {
            del(name);
        }
        

        #region 
        public static string SToUpper(string name)
        {
            return name.ToUpper();
        }
        public static string SToLower(string name)
        {
            return name.ToLower();
        }
        public static string SSYH(string name)
        {
            return "\""+name+"\"";
        }
        #endregion
        static void SayHiChinese(string name)
        {
            Console.WriteLine("吃了么?" + name);
        }

        static void SayHiEnglish(string name)
        {
            Console.WriteLine("nice to meet you " + name);
        }

        static void SayHiKorea(string name)
        {
            Console.WriteLine("o ba 思密达" + name);
        }

        static void SayHiJapanese(string name)
        {
            Console.WriteLine("o ha yo" + name);
        }
    }
}

2.委托中的模板方法
定义:相当于是一个工厂,但是这个传进工厂做工的方式,是委托,委托中有包含有方法,自我感觉功能很强大。
代码如下(示例):

namespace 委托模板方法
{
    class Program
    {
        static void Main(string[] args)
        {
            ProductFactory productFactory = new ProductFactory();
            WrapFactory wrapFactory = new WrapFactory();

            Func<Product> func1 = new Func<Product>(productFactory.MakePizze);//这里只是传方法
            Func<Product> func2 = new Func<Product>(productFactory.MakeToyCar);

            Box box1 = wrapFactory.WrapProduct(func1);
            Box box2 = wrapFactory.WrapProduct(func2);

            Console.WriteLine(box1.Product.Name);
            Console.WriteLine(box2.Product.Name);

            Console.ReadKey();
        }
    }
    class Product
    {
        public string Name { get; set; }
    }
    class Box
    {
        public Product Product { get; set; }
    }
    /// <summary>
    /// 包装产品
    /// </summary>
    class WrapFactory
    {
        public Box WrapProduct(Func<Product> getProduct)//但是这里传进去的参数是委托
        {
            Box box = new Box();
            Product product = getProduct.Invoke();//这里相当于是执行传进来的方法
            box.Product = product;
            return box;
        }
    }
    /// <summary>
    /// 这个类是生产产品,
    /// </summary>
    class ProductFactory
    {
        public Product MakePizze()
        {
            Product product = new Product();
            product.Name = "Pizza";
            return product;
        }
        public Product MakeToyCar()
        {
            Product product = new Product();
            product.Name = "Toy Car";
            return product;
        }
    }
}

2.模板方法

1.模板方法相当于是一个工厂,把大家几乎相同的一个工作,交给一个类似于工厂的方法中。
2.利用委托传入
代码如下(示例):

namespace 委托模板方法
{
    class Program
    {
        static void Main(string[] args)
        {
            ProductFactory productFactory = new ProductFactory();
            WrapFactory wrapFactory = new WrapFactory();

            Func<Product> func1 = new Func<Product>(productFactory.MakePizze);//这里只是传方法
            Func<Product> func2 = new Func<Product>(productFactory.MakeToyCar);

           
          
            Box box1 = wrapFactory.WrapProduct(func1);
            Box box2 = wrapFactory.WrapProduct(func2);

            Console.WriteLine(box1.Product.Name);
            Console.WriteLine(box2.Product.Name);

            Console.ReadKey();
        }
    }  
    class Product
    {
        public string Name { get; set; }
        public double Price { get; set; }
    }
    class Box
    {
        public Product Product { get; set; }
    }
    /// <summary>
    /// 包装产品
    /// </summary>
    class WrapFactory
    {
        public Box WrapProduct(Func<Product> getProduct)//但是这里传进去的参数是委托
        {
            Box box = new Box();
            Product product = getProduct.Invoke();//这里相当于是执行传进来的方法
            
            box.Product = product;
            return box;
        }
    }
    /// <summary>
    /// 这个类是生产产品,
    /// </summary>
    class ProductFactory
    {
        public Product MakePizze()
        {
            Product product = new Product();
            product.Name = "Pizza";
            product.Price = 10;
            return product;
        }
        public Product MakeToyCar()
        {
            Product product = new Product();
            product.Name = "Toy Car";
            product.Price = 100;
            return product;
        }
    }
}

总结

多看看,多写写,多思考,收获总会多一点

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页