zoukankan      html  css  js  c++  java
  • C#知识点总结【2】

    此文章只是 记录在C#当中一些我个人认为比较重要的知识点,对于有些基础实现或者用法并未说明;

    继承

    C#当中可以实现两种继承方式

    1.实现继承:一个类派生于一个类,它拥有基类的所有成员字段和函数。

    2.接口继承:表示一个类只继承了函数的签名,没有继承任何实现代码。

    结构支持接口继承,但不支持实现继承;

     

    虚方法

    虚方法关键字 virtual

    函数使用 virtual 关键字 子类可以重写 基类的虚方法;重写后使用重写方法;

    属性也可以使用 virtual

    如果在子类中想要使用基类的方法;那么可以使用关键字base 如:base.Name;

            public virtual string Name
            {
                get{ return name;}
                set{ name = value;}
            }
            private string name;

     

    隐藏方法

    如果子类中没有运用 重写 或者 基类中没有 虚方法 那么子类写的方法名和基类相同那么就会自动覆盖掉基类的方法;

    避免这种事情的发生 可以只用 new 关键字来扩展基类方法;

            public new void GetTwo()
            {
            
            }

    抽象类和抽象函数

    抽象关键字 abstract ;

    抽象类不能被实例化,抽象类中的函数不能被实现,必须由派生类重写;

    密封类和密封方法

    可以使用关键字 sealed;

    主要作用是 使用了该关键字就不能被继承,方法使用关键字就不能被重写;

    string 就是一个密封类;

    接口

    和抽象类相同。不能有实现;不能被实例化;不允许有成员修饰符;

    泛型

    泛型是把不同的类相同的许多方法,合并成一个公共(泛型)类;

    泛型的主要优点是性能。非泛型集合需要装箱拆箱操作大大的影响了效率;

    然后泛型集合还会根据大小自动调整内存;

    泛型允许更好的重用二进制代码

    泛型使用 T 字母;

    因为不能把null复制给泛型 可以用default 解决;

    委托

    当要把一个方法传递给另一个方法时需要使用委托;

    声明委托需要用到的关键字是 delegate ;

    如果参数中带有委托方法那么就可以直接调用lambda 表达式进行相关操作;

    有三个栗子可以 说明委托

    1.事件 最有代表性的委托;

    2.启动线程和任务  大概就是如果已经启动了一个线程现在需要启动另一个线程,那么Thread 中就有委托来帮忙完成这件事;

    3.通用类库 这个比较模糊,大概就是类库中有很多用到了委托;

    首先完成一个非常简单的委托,这样使用非常的不直观,但是也能表示出委托的意思

        class Program
        {
            delegate string GetStr();
            static void Main(string[] args)
            {
                int x = 10;
                GetStr getStr = x.ToString;
                Console.WriteLine("输出:{0}", getStr());
                Console.ReadLine();
            }
    
        }

    另一种比较直观的使用方法

            delegate double GetDouble(double x);
            static void Main(string[] args)
            {
                //第一种输出 第一个方法返回值是11,第二个是9  说明分别执行了两个方法
                GetDouble[] nums = { MultiplyByTwo, Square };
                for (int i = 0; i < nums.Length; i++)
                {
                    Proc(nums[i],10);
                }
                Console.ReadLine();
    
                //第二个只调用一次 输出为21
                Proc(MultiplyByTwo,20);
                Console.ReadLine();
               
            }
            public static double MultiplyByTwo(double y)
            {
                y++;
                return y;
            }
    
            public static double Square(double y)
            {
                y--;
                return y;
            }
    
            static void Proc(GetDouble action, double value)
            {
                double result = action(value);
                Console.WriteLine("输出:{0},改变:{1}", value, result);            
            }

    另外C#还提供了两种委托方式 那就是 Func<T>和Action<T>

    Func<T> 带返回值 ,且可以传入16个参数

        class Program
        {
            static void Main(string[] args)
            {
                //第一种输出 第一个方法返回值是11,第二个是9  说明分别执行了两个方法
                //Func 的前面都是参数类型,最后一个是里面传入的是返回值。可以添加16个参数
                Func<double,double>[] nums = { MultiplyByTwo, Square };
                for (int i = 0; i < nums.Length; i++)
                {
                    Proc(nums[i],10);
                }
                Console.ReadLine();
    
                //第二个只调用一次 输出为21
                Proc(MultiplyByTwo,20);
                Console.ReadLine();
               
            }
            public static double MultiplyByTwo(double y)
            {
                y++;
                return y;
            }
    
            public static double Square(double y)
            {
                y--;
                return y;
            }
    
            static void Proc(Func<double,double> action, double value)
            {
                double result = action(value);
                Console.WriteLine("输出:{0},改变:{1}", value, result);            
            }
        }

    Action<T> 是不带返回值,且可以传入8个参数

       class Program
        {
            static void Main(string[] args)
            {
                Action<double,double>[] nums = { MultiplyByTwo, Square };
                for (int i = 0; i < nums.Length; i++)
                {
                    Proc(nums[i],10);
                }
                Console.ReadLine();
    
                Proc(MultiplyByTwo,20);
                Console.ReadLine();
               
            }
            public static void MultiplyByTwo(double y, double x)
            {
                y++;
            }
    
            public static void Square(double y, double x)
            {
                y--;
            }
    
            static void Proc(Action<double,double> action, double value)
            {
                action(value,value);
                Console.WriteLine("输出:{0}", value);            
            }
        }

    一个高级冒泡排序

        class Program
        {
            static void Main(string[] args)
            {
                Employee[] employees = 
                {
                    new Employee("张三",1000),
                    new Employee("李四",8000),
                    new Employee("王五",7000),
                    new Employee("赵六",900)
                };
                Sort(employees, Employee.Compare);
                foreach (Employee item in employees)
                {
                    Console.WriteLine(item);
                }
                Console.ReadLine();
    
            }
            /// <summary>
            /// 高级冒泡排序
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="sortList"></param>
            /// <param name="comparison"></param>
            public static void Sort<T>(IList<T> sortList, Func<T, T, bool> comparison)
            {
                bool swapped = true;
                do
                {
                    swapped = false;
                    for (int i = 0; i < sortList.Count - 1; i++)
                    {
                        if (comparison(sortList[i + 1], sortList[i]))
                        {
                            T temp = sortList[i];
                            sortList[i] = sortList[i + 1];
                            sortList[i + 1] = temp;
                            swapped = true;
                        }
                    }
                } while (swapped);
            }
        }
        class Employee
        {
            public Employee(string name, decimal salary)
            {
                this.Name = name;
                this.Salary = salary;
            }
            public string Name { get; set; }
            public decimal Salary { get; set; }
    
            public override string ToString()
            {
                return string.Format("{0},{1:C}", Name, Salary);
            }
            public static bool Compare(Employee e1, Employee e2)
            {
                return e1.Salary < e2.Salary;
            }
        }

    匿名委托

    前面到的委托都是有一个方法来实现委托,现在就来说一下没有方法时候怎么实现委托(面试时候如果让写一个委托其实可以完全写这一种方式,因为简单,又能表达出委托的意义)

        class Program
        {
            static void Main(string[] args)
            {
                string name = "我叫张三";
                Func<string, string> outName = delegate(string param) 
                {
                    param += ",你叫什么?";
                    return param;
                };
                Console.WriteLine(outName(name));
                Console.ReadLine();
            }
        }

    多播委托

    那么有人说了,Func 完全可以代替 Action 了啊,要他没啥用,其实 还有一种 叫多播委托 就需要用到返回值为void 的委托方式,因为需要调用多个委托,所以不能有返回值;

        class Program
        {
            static void Main(string[] args)
            {
                Action<double> operations = MathOperations.One;
                operations += MathOperations.Two;
                Write(operations,20);
                Write(operations, 30);
                Console.ReadLine();
    
            }
            static void Write(Action<double> action, double value)
            {
                Console.WriteLine("原始值:{0}", value);
                action(value);
            }
        }
        class MathOperations
        {
            public static void One(double y)
            {
                double result = y * 2;
                Console.WriteLine("乘2:{0}", result);
            }
            public static void Two(double y)
            {
                double result = y / 2;
                Console.WriteLine("除2:{0}", result);
            }
        }

    Lambda表达式

    lambda表达式在 C#使用非常广泛。上面那个匿名委托就可以改成

                //一个参数
                string name = "我叫张三";
                Func<string, string> outOne = param =>
                {
                    param += ",你叫什么?";
                    return param;
                };
                Console.WriteLine(outOne(name));

    同时还可以传入多个参数.

                //多个参数
                Func<string, string, string> outTwo = (param, paramTwo) =>
                {
                    param += ",你叫什么?";
                    paramTwo += ",你的性别?";
                    return param + paramTwo;
                };
                Console.WriteLine(outTwo(name, "我是男的"));

    闭包 闭包是非常危险的,如果使用不妥善,很容易出错

                //闭包
                //理论上这个num是外部变量,在方法内部是没法访问的。
                //但是在lambda中可以访问,虽然方便但也危险;
                //这段代码输出的是 8
                int num = 5;
                Func<int, int> f = x => x + num;
                num = 7;
                Console.WriteLine(f(1));

    同时还可以使用List 的foreach 5.0对他有了很大的改善;

                //在C#5.0对 foreach 闭包有了很大的改善
                var values = new List<int> { 1, 2, 3, 4 };
                var funcs = new List<Func<int>>();
    
                foreach (var item in values)
                {
                    funcs.Add(() => item);
                }
                foreach (var fun in funcs)
                {
                    Console.WriteLine(fun());
                }

    事件

    事件基于委托,在C#中到处都可以看到事件的影子,比如:button 的 click事件;

    这里就不在写代码来描述事件的写法;其实就是把委托换了一种简洁的方式写出来;

    通过事件可以链接倒发布程序和监听器,但是如果监听器不在监听,那么就是发布程序扔有引用,这就没法回收掉;

    那么就可以使用 WeakEventManager 来创建 弱事件;

    名称:多罗贝勒
    博客地址:http://www.cnblogs.com/objctccc/
    欢迎转载

  • 相关阅读:
    Linux查找日志技巧
    win10编辑hosts文件提示没有权限
    Viso 2019 下载与激活
    SpringBoot日志记录组件logback的配置解释
    webservice(axis)接口上传文件附件 及 用zlib解压缩
    axis2添加接口过程
    关于“finally block does not complete normally”警告提示
    webservice介绍与流程(杂)
    JDBC理解
    Myeclipse中调整xml中字体显示大小
  • 原文地址:https://www.cnblogs.com/objctccc/p/6121558.html
Copyright © 2011-2022 走看看