C# 备忘录

①访问限制

  1. public:所有类均可使用
  2. internal:同一命名空间(程序集)中的类可以使用
  3. protected:在本类中及其子类中可以使用
  4. private:只能在本类中使用,默认。

     从上到下,访问限制逐渐升高

②using用法

  1. 引入命名空间
  2. 定义别名
  3. 定义临时块范围,在该范围结束时回收资源。

③new用法

  1. 用作运算符:创建对象和调用构造函数。 
  2. 用作修饰符:隐藏从基类继承的属性、字段、方法(因为不能删除,所以选择隐藏),用于关闭警告。
  3. 用作约束:在泛型声明中约束可能用作类型参数的参数类型。

④常用快捷键

  1. 进入MSDN/查看帮助:F1
  2. 启动调试:F5,直接运行:Ctrl+F5
  3. 试图转向代码:F7,代码转向试图:Ctrl+F7
  4. 设置/取消断点:F9
  5. 单步调试:F10
  6. 逐句调试:F11
  7. 转到定义处:F12

⑤重载、重写、覆盖

  1. 重载指的是同一个类中有两个或多个名字相同但是参数个数、次序、类型不同的方法,(注:返回值可相同可不同),重载没有关键字。
  2. override:重写是指子类对父类中虚函数或抽象函数的“覆盖”,实现新的功能,它必须和父类方法的方法名、参数、返回类型、访问修饰符完全一致。但是这种“覆盖”和用new关键字来覆盖是有区别的,通过指向子类的父类对象不能调用到被重写的父类方法,但父类对象本身仍可以调用到父类方法。
  3. new:覆盖指的是不同类中(基类或派生类)有两个或多个返回类型、方法名、参数都相同,但是方法体不同的方法。但是这种覆盖是一种表面上的覆盖,所以也叫隐藏,通过指向子类的父类对象可以调用到被重写的父类方法,父类对象本身当然也可以调用到父类方法。

      综上:

  1. 重载,必然发生在一个类中,函数名相同,参数类型或者顺序不同构成重载,与返回类型无关
  2. 重写,必然发生在基类和派生类中,基类函数用virtual或abstract修饰,派生类用override修饰
  3. 覆盖,在子类中写一个和基类一样名字(参数不同也算)的非虚函数,会让基类中的函数被隐藏,编译后会提示要求使用New关键字

⑥结构struct与类class的区别

    1. 值类型与引用类型 
        结构是值类型:值类型在堆栈上分配地址,所有的基类型都是结构类型,例如:int 对应System.int32 结构,通过使用结构可以创建更多的值类型 
        类是引用类型:引用类型在堆上分配地址 ,例如string
        堆栈的执行效率要比堆的执行效率高,可是堆栈的资源有限,不适合处理大的逻辑复杂的对象。所以结构处理作为基类型对待的小对象,而类处理某个商业逻辑 
        因为结构是值类型,所以结构之间的赋值是创建新的结构,而类是引用类型,类之间的赋值只是复制引用 
    注: 
        a.虽然结构与类的类型不一样,可是他们的基类型都是对象(object),c#中所有类型的基类型都是object 
        b.虽然结构的初始化也使用了New 操作符可是结构对象依然分配在堆栈上而不是堆上,如果不使用“新建”(new),那么在初始化所有字段之前,字段将保持未赋值状态,且对象不可用 

    2.继承性 
        结构:不能从另外一个结构或者类继承,本身也不能被继承,虽然结构没有明确的用sealed声明,可是结构是隐式的sealed . 
        类:完全可扩展的,除非显示的声明sealed 否则类可以继承其他类和接口,自身也能被继承 
        注:虽然结构不能被继承,可是结构能够继承接口,方法和类继承接口一样 

    3.内部结构: 
        结构: 
            没有默认的构造函数,但是可以添加构造函数 (结构体中不能定义默认的、不带参数的构造函数,只能定义带参的构造函数)
            没有析构函数 
            没有 abstract 和 sealed(因为不能继承) 
            不能有protected 修饰符 
            可以不使用new 初始化 
            在结构中初始化实例字段是错误的 
        类: 
            有默认的构造函数 (可以定义默认的、不带参数的构造函数,或者带参的构造函数)
            有析构函数 
            可以使用 abstract 和 sealed 
            有protected 修饰符 
            必须使用new 初始化

扫描二维码关注公众号,回复: 1096322 查看本文章

⑦实例化过程、this、base

    1)先不考虑继承关系,执行顺序为:

        静态字段
        静态构造方法
        实例字段
        实例构造方法

    2)考虑继承关系,执行顺序为:

        子类的静态字段
        子类的静态构造方法
        子类的实例字段
        父类的静态字段
        父类的静态构造方法
        父类的实例字段
        父类的实例构造方法
        子类的实例构造方法

    3)this关键字 
        this关键字代表当前对象,通过this关键字可以访问当前对象的成员。(当前对象的成员:自己本身的成员+从父类继承过来的所有的成员。)

        this关键字可以访问:本类的所有成员和父类的非私有成员。父类的私有成员确实存在,但是就是访问不到。
        this关键字仍然代表的是对象,通过它可以点出对象中的除了父类的私有成员以外的所有成员。
        this关键字只能用在实例方法中。
        作用:
            1)代表当前对象。在实例方法中使用this关键字就代表当前对象。通过this关键字可以点出本类的所有成员和父类的非私有成员。
            2)调用本类的其他的构造函数。在构造函数的后面的this代表调用本类的其他的构造函数。

    4)base关键字

        显示的访问父类的非私有成员。可以访问子类对象中的父类的非私有成员。base不代表父类对象。因为压根就没有父类对象。通过它可以访问到父类的非私有成员。通过this关键字访问当前对象的成员的时候:先找子类本身有没有这个成员,如果没有再找是否有从父类继承过来的。base关键字 直接就找父类中的成员。我们发现,base可以点出来的成员,通过this都可以点出来访问。

        建议:如果我们访问的确实是从父类继承过来的,那么建议用base关键字访问,这样方便代码的阅读和提高效率。只有在访问的成员确实是子类独有的,那么我们才用this关键字。

        作用:

            1)在实例方法中,通过base关键字可以显示的访问子类对象中的非私有的父类成员。

            2)调用父类的构造函数。在子类的构造函数的后面的base代表调用父类的构造函数。

⑧抽象类abstract,接口interface,密封类sealed

    1)abstract修饰符可以和类,方法,属性,索引及事件一起使用。
    在类声明时使用abstract修饰符,以指示该类只能是其他类的基类,标记为抽像或包含在抽像类中的成员必须在抽像类的派生类中实现;
    抽象类特性:
        抽像类不能实例化。
        抽像类可以包含抽象方法和抽像访问器。
        不能用sealed修饰符修改抽像类。
    抽像方法特性:
        是隐式的virtual方法。
        只能在抽像类中使用抽像方法声明。
        不提供实际的实现。
        具体实现由override方法提供,它是非抽像类的成员。
        使用static或virtual修饰符是错误的。
    即:abstract是一种抽象,好比上帝,是人们对神的抽象,看似什么都能做,其实什么都做不了。

    2)接口的定义:
        接口的定义是指定一组函数成员而不实现成员的引用类型,其它类型和接口可以继承接口。
        接口主要有以下特点:
            1)通过接口可以实现多重继承,C#接口的成员不能有public、protected、internal、private等修饰符。原因很简单,接口里面的方法都需要由外面接口实现去实现方法体,那么其修饰符必然是public。C#接口中的成员默认是public的,java中是可以加public的。
            2)接口成员不能有new、static、abstract、override、virtual修饰符。有一点要注意,当一个接口实现一个接口,这2个接口中有相同的方法时,可用new关键字隐藏父接口中的方法。
            3)接口中只包含成员的签名,接口没有构造函数,所有不能直接使用new对接口进行实例化。接口中只能包含方法、属性、事件和索引的组合。接口一旦被实现,实现类必须实现接口中的所有成员,除非实现类本身是抽象类。
            4)C#是单继承,接口是解决C#里面类可以同时继承多个基类的问题。

    3)接口和抽象类的区别:
        接口用于规范,抽象类用于共性。抽象类是类,所以只能被单继承,但是接口却可以一次实现多个。
        接口中只能声明方法,属性,事件,索引器。而抽象类中可以有方法的实现,也可以定义非静态的类变量。
        抽象类可以提供某些方法的部分实现,接口不可以。抽象类的实例是它的子类给出的。接口的实例是实现接口的类给出的。
        在抽象类中加入一个方法,那么它的子类就同时有了这个方法。而在接口中加入新的方法,那么实现它的类就要重新编写(这就是为什么说接口是一个类的规范了)。
        接口成员被定义为公共的,但抽象类的成员也可以是私有的、受保护的、内部的或受保护的内部成员(其中受保护的内部成员只能在应用程序的代码或派生类中访问)。此外接口不能包含字段、构造函数、析构函数、静态成员或常量。
        还有一点,我们在VS中实现接口时会发现有2个选项,一个是实现接口,一个是显示实现接口。实现接口就是我们平常理解的实现接口,而显示实现接口的话,实现的方法是属于接口的,而不是属于实现类的。

4)密封类sealed

        密封类不能被继承,
        密封方法可以重写基类中的方法,但其本身不能在任何派生类中进一步重写,当应用于方法或属性时,sealed修饰符必须始终于override一起使用

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

namespace PetShop
{
    /// <summary>
    /// 接口interface:指定一组成员函数,但本身不实现它们
    /// </summary>
    interface ICatchMice
    {
        /// <summary>
        /// 默认public,但不能加public
        /// </summary>
        void CatchMice();
    }
    interface IClimbTree
    {
        void ClimbTree();
    }

    /// <summary>
    /// 父类、基类,所有类都继承于Object,省略时默认继承于Object
    /// </summary>
    public class Pet
    {
        protected string name;
        protected int age;
        /// <summary>
        /// 构造函数
        /// </summary>
        public Pet() { }
        public Pet(string name) {
            this.name = name;
            this.age = 0;
        }
        /// <summary>
        /// 成员函数
        /// </summary>
        public void PrintName()
        {
            Console.WriteLine("Pet`s name is " + this.name);
        }
        public void PrintAge()
        {
            Console.WriteLine(this.name + "`s age is " + this.age);
        }
        /// <summary>
        /// 虚方法
        /// </summary>
        virtual public void Speak()
        {
            Console.WriteLine("Pet is speaking");
        }
        /// <summary>
        /// 重载运算符
        /// </summary>
        /// <param name="pet">Pet对象</param>
        /// <returns>将Pet对象的年龄加1后返回</returns>
        public static Pet operator ++(Pet pet)
        {
            ++pet.age;
            return pet;
        }
        /// <summary>
        /// 泛型方法:可以包含在泛型类中,也可以包含在普通类中
        /// 约束规则:一个泛型类(类名或class或struct),多个接口(接口名),new()
        /// </summary>
        /// <param name="target">T类型的对象</param>
        public void IsHappy<T>(T target) where T:Pet
        {
            Console.WriteLine(target.ToString()+ " is happy");
        }
    }

    /// <summary>
    /// 单继承:只能继承于一个父类
    /// </summary>
    public class Dog : Pet
    {
        /// <summary>
        /// 静态成员字段
        /// </summary>
        static int num;
        /// <summary>
        /// 委托与事件发布者
        /// </summary>
        public delegate void Handler();
        public static event Handler NewDog;
        /// <summary>
        /// 静态构造方法中不允许出现访问修饰符
        /// </summary>
        static Dog()
        {
            num = 0;
        }
        /// <summary>
        /// this表示当前对象,base表示父类对象
        /// </summary>
        /// <param name="name">初始化名字</param>
        public Dog(string name):base(name)
        {
            //this.name = name;
            num++;
            //触发事件
            if (NewDog != null)
            {
                NewDog();
            }
        }
        /// <summary>
        /// 隐藏
        /// </summary>
        new public void PrintName()
        {
            Console.WriteLine("宠物狗的名字是" + this.name);
        }
        /// <summary>
        /// 重写
        /// </summary>
        override public void Speak()
        {
            Console.WriteLine("Dog is speaking" + " wow");
        }
        /// <summary>
        /// 静态方法只能访问静态成员,非静态方法可以访问静态也可以访问非静态成员
        /// 静态方法只能通过类名调用,非静态方法只能通过对象访问
        /// </summary>
        public static void ShowNum()
        {
            Console.WriteLine("Dog's number is " + num);
        }
        /// <summary>
        /// 自定义类的隐式转换
        /// </summary>
        /// <param name="dog">原始类对象</param>
        /// <returns>目标类对象</returns>
        public static implicit operator Cat(Dog dog)
        {
            return new Cat(dog.name);
        }
        /// <summary>
        /// 被委托方法
        /// </summary>
        public void WagTail()
        {
            Console.WriteLine(this.name + " wag tail");
        }
    }

    /// <summary>
    /// 类是单继承,接口是多实现
    /// </summary>
    public class Cat : Pet,ICatchMice,IClimbTree
    {
        public Cat(string name):base(name)
        {
            //this.name = name;
        }
        /// <summary>
        /// 隐藏
        /// </summary>
        new public void PrintName()
        {
            Console.WriteLine("宠物猫的名字是" + this.name);
        }
        /// <summary>
        /// 重写
        /// </summary>
        override public void Speak()
        {
            Console.WriteLine("Cat is speaking" + " mom");
        }
        /// <summary>
        /// 必须实现接口里的全部函数
        /// </summary>
        public void CatchMice()
        {
            Console.WriteLine("Catch Mice");
        }
        public void ClimbTree()
        {
            Console.WriteLine("Climb Tree");
        }
       /// <summary>
        /// 自定义类的显式转换
       /// </summary>
       /// <param name="cat">原始类对象</param>
       /// <returns>目标类对象</returns>
        public static explicit operator Dog(Cat cat)
        {
            return new Dog(cat.name);
        }
        /// <summary>
        /// 被委托方法
        /// </summary>
        public void InnocentLook()
        {
            Console.WriteLine(this.name + " innocent look");
        }
    }

    /// <summary>
    /// 实现泛型接口
    /// </summary>
    public class Labrador : Dog, ILearn<SitDogCmd>, ILearn<SpeakDogCmd>
    {
        public Labrador(string name) : base(name) { }
        public void Act(SitDogCmd cmd)
        {
            Console.WriteLine(cmd.GetCmd());
        }
        public void Act(SpeakDogCmd cmd)
        {
            Console.WriteLine(cmd.GetCmd());
        }
    }

    /// <summary>
    /// 抽象类,抽象方法
    /// </summary>
    public abstract class DogCmd
    {
        public abstract string GetCmd();
    }

    /// <summary>
    /// 实现抽象类,重写抽象方法
    /// </summary>
    public class SitDogCmd : DogCmd
    {
        public override string GetCmd()
        {
            return "Sit Down";
        }
    }
    public class SpeakDogCmd : DogCmd
    {
        public override string GetCmd()
        {
            return "wow";
        }
    }

    /// <summary>
    /// 继承抽象类并实现抽象属性或抽象方法
    /// </summary>
    public class DogFood:Food
    {
        private double weight;
        /// <summary>
        /// 使用override重写抽象属性
        /// </summary>
        override public double Weight {
            get { return weight; }
            set { weight = value; }
        }
        /// <summary>
        /// 使用override重写抽象方法
        /// </summary>
        public override void NiceFood()
        {
            Console.WriteLine("大黄牌狗粮");
        }
    }

    /// <summary>
    /// 静态类
    /// </summary>
    public static class PetGuide
    {
        /// <summary>
        /// 静态方法与静态类之间没有必然关系(类似sealed)
        /// </summary>
        /// <param name="dog"></param>
        public static void HowToFeed(this Dog dog)
        {
            Console.WriteLine("play a vedio about how to feed dog!");
        }
    }

    /// <summary>
    /// 泛型类:类的模板
    /// </summary>
    /// <typeparam name="T">具体类型</typeparam>
    public class Cage<T> where T:Pet
    {
        T[] PetArr;
        readonly int ArrSize;
        int num;
        public Cage(int n)
        {
            ArrSize = n;
            num = 0;
            PetArr = new T[ArrSize];
        }
        public void PutIn(T pet)
        {
            if (num < ArrSize)
            {
                PetArr[num++] = pet;
            }
            else
            {
                Console.WriteLine("Cage is full!");
            }
        }
        public T TakeOut()
        {
            if (num > 0)
            {
                return PetArr[--num];
            }
            else
            {
                Console.WriteLine("Cage is empty!");
                return default(T);
            }
        }
    }

    /// <summary>
    /// 泛型接口:接口的模板
    /// </summary>
    /// <typeparam name="T"></typeparam>
    interface ILearn<C> where C:DogCmd
    {
        void Act(C cmd);
    }

    /// <summary>
    /// 事件的订阅者
    /// </summary>
    public class Client
    {
        public void WangADog()
        {
            Console.WriteLine("Great!  I want to see the new dog");
        }
    }

    class Program
    {
         /// <summary>
         /// 委托方法
         /// </summary>
        delegate void ActCute();

        static void Main(string[] args)
        {
            //继承,隐藏,虚方法,构造方法
            {
                Pet pet = new Pet("萌萌");
                pet.PrintName();
                pet.Speak();
                Dog dog = new Dog("小白");
                dog.PrintName();
                dog.Speak();
                Cat cat = new Cat("小花");
                cat.PrintName();
                cat.Speak();
            }
            // 使用基类类型的数组作为对象容器
            {
                Pet[] pets = new Pet[] { new Pet("萌萌"), new Dog("小白"), new Cat("小花") };
                foreach (Pet p in pets)
                {
                    p.PrintName();
                    p.Speak();
                }
            }
            //抽象类与抽象方法
            {
                DogFood dogFood = new DogFood();
                dogFood.Weight = 50;
                dogFood.NiceFood();
            }
            //实现接口
            {
                Cat cat2 = new Cat("Tom");
                ICatchMice icm = (ICatchMice)cat2;
                IClimbTree ict = (IClimbTree)cat2;
                cat2.CatchMice();//通过类调用实现了的接口函数
                icm.CatchMice();//通过接口调用其中包含的函数
                cat2.ClimbTree();
                ict.ClimbTree();
            }

            //静态成员
            {
                Dog.ShowNum();
            }
            //静态类
            {
                Dog dog2 = new Dog("激萌的小黑");
                dog2.HowToFeed();
            }

            //装箱与拆箱
            {
                int i = 5;
                object o = i;//自动装箱:将值类型转换为引用类型
                i = 10;
                o = 20;
                int j = (int)o;//手动拆箱:将装箱后的对象转换为值类型
                Console.WriteLine("i = " + i + ",o = " + o + ",j = " + j);
            }
            //自定义类转换
            {
                Dog dog3 = new Dog("激萌的小黄");
                dog3.PrintName(); dog3.Speak();
                Cat cat3 = dog3;
                cat3.PrintName(); cat3.Speak();
                Dog dog4 = (Dog)cat3;
                dog4.PrintName(); dog4.Speak();
            }
            // 重载运算符
            Pet[] petss = new Pet[] { new Pet("萌萌"), new Dog("小白"), new Cat("小花") };
            for (int i = 0; i < petss.Length; i++)//此处注意for与foreach的区别
            {
                petss[i].PrintAge();
                petss[i]++;
                petss[i].PrintAge();
            }

            //泛型类:功能类似一个类模板
            {
                var DogCage = new Cage<Dog>(1);
                DogCage.PutIn(new Dog("A"));
                DogCage.PutIn(new Dog("B"));
                DogCage.TakeOut().PrintName();
                //DogCage.TakeOut().PrintName();
                var CatCage = new Cage<Cat>(1);
                CatCage.PutIn(new Cat("C"));
                CatCage.PutIn(new Cat("D"));
                CatCage.TakeOut().PrintName();
                //CatCage.TakeOut().PrintName();
            }
            //泛型方法:方法的模板
            {
                new Pet().IsHappy<Cat>(new Cat("B"));
                //new Pet().IsHappy<int>(3);
            }
            //约束:缩小泛型参数的范围,可应用于泛型类和泛型方法
            {
                var DogCage = new Cage<Dog>(1);
                DogCage.PutIn(new Dog("A"));
                DogCage.TakeOut().PrintName();
                //var icCage = new Cage<IClimbTree>(1);
                new Pet().IsHappy<Cat>(new Cat("B"));
                //new Pet().IsHappy<int>(3);
            }
            //泛型接口
            {
                Labrador dog = new Labrador("A");
                dog.Act(new SitDogCmd());
                dog.Act(new SpeakDogCmd());
            }

            //列表List,动态数组ArrayList,字典Dictionary,栈Stack,队列Queue
            {
                List<Pet> plist = new List<Pet>();
                plist.Add(new Pet("萌萌"));
                plist.Add(new Dog("小白"));
                plist.Add(new Cat("小花"));
                plist.RemoveAt(1);
                foreach (Pet p in plist)
                {
                    p.PrintName();
                }

                Dictionary<string, Dog> ddic = new Dictionary<string, Dog>();
                ddic.Add("A", new Dog("A"));
                ddic.Add("B", new Dog("B"));
                ddic.Add("C", new Dog("C"));
                ddic["A"].PrintName();

                Stack<Pet> pstack = new Stack<Pet>();
                pstack.Push(new Dog("AA"));
                pstack.Push(new Cat("BB"));
                pstack.Peek().PrintName();
                pstack.Pop();
                pstack.Peek().PrintName();
                pstack.Pop();

                Queue<Pet> pqueue = new Queue<Pet>();
                pqueue.Enqueue(new Dog("AAA"));
                pqueue.Enqueue(new Cat("BBB"));
                pqueue.Dequeue().PrintName();
                pqueue.Dequeue().PrintName();
            }

            //委托
            {
                ActCute actCute = new Dog("A").WagTail;
                actCute += new Cat("B").InnocentLook;
                actCute();
            }
            //Lambda表达式
            {
                ActCute actCute = new Dog("A").WagTail;
                actCute += new Cat("B").InnocentLook;
                actCute += () =>
                {
                    Console.WriteLine("do nothing");
                };
                actCute();
            }
            //事件:发布者,订阅者,触发事件,注册事件
            {
                Client c1 = new Client();
                Client c2 = new Client();
                // 注册事件
                Dog.NewDog += c1.WangADog;
                Dog.NewDog += c1.WangADog;
                new Dog("小Q");
            }
        }
       
    }
}










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

namespace PetShop
{
    /// <summary>
    /// 包含抽象方法的类是抽象类
    /// </summary>
    abstract public class Food
    {
        public double price;
        /// <summary>
        /// 抽象属性
        /// </summary>
        abstract public double Weight
        {
            get;
            set;
        }
        /// <summary>
        /// 抽象方法
        /// </summary>
        abstract public void NiceFood();
    }
}

课程地址:

https://www.imooc.com/learn/422
https://www.imooc.com/learn/554
https://www.imooc.com/learn/806

猜你喜欢

转载自my.oschina.net/MasterLi161307040026/blog/1648809
今日推荐