欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > C# >内容正文

C#

C# 备忘录

发布时间:2025/3/20 C# 64 豆豆
生活随笔 收集整理的这篇文章主要介绍了 C# 备忘录 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

2019独角兽企业重金招聘Python工程师标准>>>

①访问限制

  • public:所有类均可使用
  • internal:同一命名空间(程序集)中的类可以使用
  • protected:在本类中及其子类中可以使用
  • private:只能在本类中使用,默认。
  •      从上到下,访问限制逐渐升高

    ②using用法

  • 引入命名空间
  • 定义别名
  • 定义临时块范围,在该范围结束时回收资源。
  • ③new用法

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

  • 进入MSDN/查看帮助:F1
  • 启动调试:F5,直接运行:Ctrl+F5
  • 试图转向代码:F7,代码转向试图:Ctrl+F7
  • 设置/取消断点:F9
  • 单步调试:F10
  • 逐句调试:F11
  • 转到定义处:F12
  • ⑤重载、重写、覆盖

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

  • 重载,必然发生在一个类中,函数名相同,参数类型或者顺序不同构成重载,与返回类型无关
  • 重写,必然发生在基类和派生类中,基类函数用virtual或abstract修饰,派生类用override修饰
  • 覆盖,在子类中写一个和基类一样名字(参数不同也算)的非虚函数,会让基类中的函数被隐藏,编译后会提示要求使用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 初始化

    ⑦实例化过程、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

    转载于:https://my.oschina.net/MasterLi161307040026/blog/1648809

    总结

    以上是生活随笔为你收集整理的C# 备忘录的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。