C#进阶语法**总结
## 目录### 类定义、对象、类和对象使用、属性、抽象类、静态成员、静态类、密封类、构造函数、私有构造函数、析构函数、this关键字、索引器、索引器重载三大特征封装、继承、多态接口命名空间异常处理**机器视觉开发的 “灵魂”不学这些 你永远只能写简单代码做不了真正的视觉项目**###### 视觉里干什么类、对象、属性、构造函数相机、光源、算法工具、参数配置、设备控制类。 --所有视觉 SDK、相机、图像算法**全是类 对象**。静态成员、静态类全局日志、全局配置、工具方法图像处理、坐标转换、相机公共方法。 --视觉项目里 80% 工具类都是静态类三大特性封装把相机操作封装起来外部只调用 Open() Shot()把算法封装起来外部只调用 Process()代码安全、不乱、不崩溃工业视觉最看重的就是封装继承海康相机、大恒相机、迈德思相机 → 统一继承一个父类代码结构超级清晰换相机不用重写代码大型视觉项目必用继承多态不同相机调用同一个方法名 Capture()不同算法调用同一个方法名 Run()多态 视觉插件化架构核心接口超级重要定义相机规范定义算法规范定义设备通讯规范模块化、插拔式开发机器视觉架构 90% 都靠接口抽象类定义相机模板。定义算法模板。强制子类必须实现某些功能。抽象类 视觉框架的骨架密封类、this、索引器安全控制。防止类被继承乱改。设备数据集合访问。属于进阶规范工业代码必写构造函数、析构函数相机初始化。释放相机资源。释放内存。防止内存泄漏、相机卡死。视觉项目最容易崩的地方全靠它稳住。异常处理try-catch相机打不开抓拍失败、算法报错、设备断开、图像为空。没有异常处理 视觉软件一运行就崩。命名空间引用海康、大恒SDK引用图像处理库模块化管理代码。**不用命名空间你根本无法调用视觉库**学了能做相机控制、图像处理、光源控制、算法流程、工业软件、机器视觉上位机。## 进阶语法C#类进行抽象。定义类关键字class 默认internal 一般是public默认internal 通过class声明定义一个类名 一个或多个成员变量属性名一般和字段名称相对应属性名一般是大写。字段名类似变量名首字母小写。对应属性完整封装写法。定义一个或多个成员方法。 没有返回值类型用void有就指定返回值类型。简单类成员变量、成员属性、成员方法 比较复杂事件、索引器、构造函数、析构函数--一般不怎么用来定义。指定类和成员方法访问修饰符。属性实际值存在运行字段里面。自动属性编译器去创建。对象也叫类的实例用new关键字创建对象--实例化这个类。对象地址存变量里面。引用类型对象存堆里。引用类型变量不是对象。 了解基本方式。实例化一个对象声明另一个对象实例化对象赋给它。通过任何一个对象访问里面属性调用里面方法。实例化两个course类型对象对这个对象进行简单的赋值course1和course2也一样。通过类去创建对象通过对象操作类中的属性、方法、字段最后可以通过变成处理实现想要结果。初始化--赋值--调用成员方法--输出信息。属性类、结构体、属性、字段都可以包含的成员。通过属性读写类或字段变量的值。get访问器获取字段的值set访问器修改字段的值。 获取值 修改内部私有字段的值。 只读只写可少都是可读可写包含get和set的都是属性。给属性赋值就是修改值。自动属性未显示自定义要读写的字段。定义属性三种方式完整封装自动封装get set自定义逻辑。 get出现return这条语句之前逻辑获取它本身的值然后再把他本身的值转换处理处理后返回处理后的值。一般没有自定义检查或处理逻辑吧自定义字段的值返回回去就行。普通类不能定义抽象成员。给一个入口获取字段和私有字段的值就是属性。抽象类才能创建属性。抽象类不能声明密封类。如果一个类是抽象的在他里面成员可以再子类里面进行实现。**封装** → 字段、属性、访问修饰符**继承** → **父类、子类、abstract****多态** → 重写、virtual、override非抽象类中不能定义抽象属性抽象方法也一样。抽象类不能使用new关键字进行实例化一个抽象类。 AbPeople studentnew Student();抽象类定义基本规则关键字成员定义)实现类派生类写冒号 派生于AbPeople实现抽象成员属性和方法 只要抽象成员都能实现属性和方法实例化抽象对象通过实现类中的派生类创建实例给成员赋值调用成员方法执行的方法还是实现类里面实现逻辑。静态成员一个类中字段、方法、事件都叫静态成员。 函数就是方法 普通类可以定义实例成员也可定义静态成员。静态类只能是静态成员。索引器和析构函数是实例成员 静态成员访问直接通过类访问**不需要** new 实例对象。静态变亮、属性--类成员不是实例成员静态成员通过类访问不能通过实例成员访问。静态变量也叫字段。类名.属性名/变量名静态变量泛型、集合、数组 通过类名访问静态成员**静态方法 不能直接访问 非静态实例成员****静态方法 只能访问 静态成员** 局部变量可以定义并使用不能定义静态局部变量。 静态属性会少。静态对局部无效方法内部不能定义静态变量。 静态是类成员不是局部变量。静态方法也是静态成员通过类名调如果在外部调另一个类里面静态方法通过类名调。**静态 对局部变量无效****方法内部 ➡️ 不能定义静态变量****静态只能写在类层级不能写在方法里**静态类里面的类成员也必须是静态的。界面输入信息大都是字符串类数字字符串转换成整形通过类名调静态成员是类成员。实例构造函数非静态静态构造函数只能构造一次。静态类中所有成员都必须是静态的。封装通用处理类就是通用处理方法。密封类不能被派生。不能被继承、不能被派生。构造函数不能主动调用的一类方法。创建类的对象时候会自动调用。实例构造带参和不带参。 多用于属性初始化里面其他成员也可以。类里面字段封装成属性更安全。用new创建初始化类中变量和函数。类中封装成属性更安全。构造访问修饰符public任意成员属性或变量进行初始化。无法在外部实例化私有构造函数。如果没有显示定义构造函数默认有一个无参构造函数。当用new创建对象时就会执行无参构造函数。string默认值是null带参构函提供定义就可以用。如果一个静态类有静态属性通过非静态类构建。如果一个非静态类的静态属性构建也通过静态类。如果类中定义了显示构造函数里面可以没有主题方法里边没有逻辑也可以有逻辑。默认没有显示带参构造函数可以不定义无参构造函数如果显示定义带参必须要显示定义一个无参除非不需要通过无参构造创建。如果仍然允许通过无参构造必须得显示定义一个要不然会报错。如果只有带参构造函数没有不带参构造函数实例化时候想要调用无参就不会隐式创建无参。除非没有构造函数才会隐式创建如果有构造函数没有无参就会隐式创建无参。一个类可以带参可以无参可以调用。静态构造函数只会执行一次会在实例构造之前执行。静态方法不能访问非静态成员。第二次执行实例构造函数不会执行静态构造。不能使用访问修饰符不能使用参数--静态构造函数类或结构体只能有一个带参构造函数无参不能继承或重载。不能直接调用只能CLR调用自动调用。先执行再访问先执行后调用 创建实例在构造函数之前。静态构函特征只执行一次最先执行。实现谁在谁之前调用。创建第一个实例或引用静态成员之前。理解特性几点。通过md文档来执行清楚调用点、调用方式、特征。 静态类普通类很少用静态构造普通类、非静态类只需要执行一次操作可以在里面执行。练习跑一下嵌套类基本不用。外部无法构建实例。都可以初始化成默认值。这个对象已经创建实例唯一一个不同时创建多个不同对象。另外创建爱你一个实例通过方法访问。私有静态成员为空调用私有构函创建第一次调用方法第二次调用方法直接返回。单利效果程序运行期间如果没有重复释放之前不能创建第一次创建后执行构造返回实例第二次再来构造给返回回去。两个对象一个实例。**全局只允许 1 个实例**第一次 new 才创建对象、执行构造**第二次及以后调用直接返回已有实例不会新建两个引用共用一个对象**。登陆了不能重复登录重复多次实现用公开构函不用私有嵌套类基本不用私有构造不能在外边直接调用。重复多次创建实例化用公开不能用私有。构造函数是私有不能调用。 静态构函从内部返回一个私有实现。析构函数不在释放资源做一些清理工作一般不用。析构函数只能在类中定义不能用于结构体。前面加~ 无返回值只有类类型才能包含析构函数。构造函数new时候会自动调用。 析构函数释放时候调用。 主要做清理工作。 释放就能实现这个接口。创建实例--释放资源--退出系统以后析构函数几乎不用。知道析构函数了解基本特征今后面试会问析构函数。释放时候才去调。释放资源后做一些清理垃圾回收工作。this关键字主要是成员变量和成员属性--串联构造函数定义类的索引器。通过this访问成员变量。构造函数没有继承一说this表串联。、、访问类里面集合定义索引器。用this关键字修饰的方法叫扩展方法。包含索引器必须是list集合列表。字符串也可以作为索引器。扩展方法类是静态类扩展方法是静态方法。this关键字-扩展方法索引器用中括号索引器允许重载声明一个类可以声明多个索引可以是字符串类型。遍历不能同时对它赋值。哪一个名称与索引号一样--索引器重载针对集合类型通过访问集合类型元素可以用。编号索引字符串索引子类访问修饰符不能高于基类C#只支持单继承不支持多继承。以I开头的不支持。接口定义一系列方法成员而且不支持实现多个基类但可以实现多个接口后面可以跟一个或多个接口基类只能有一个只能有一个class基类但可以实现一个或多个接口。--多重继承。C#多重继承通过接口来。一个类可以实现一个或多个接口。什么叫继承 继承派生类与子类是什么 单继承 继承传递 C#如何实现多重继承方法重载多态静态多态调用时直接绑定。方法重载方法名相同、参数个数或参数类型不同、返回值可以不同可以相同。想调用方法对应方法参数列表传对应方法实参列表。运算符重载方式掌握前提封装一个重载方法。虚方法与覆写与继承相关虚方法重写先定义一个基类虚方法在基类里面定义。重写虚方法封装一个属性就可以不重写如果有也可以没有必须声明主体。运行时多态不管创建谁最后都执行子类重写的方法。非虚方法覆写覆盖基类虚方法。运行时多态也叫动态多态。抽象方法只能在抽象类中定义类似接口中定义的方法。虚方法要有方法体方法体是空的抽象方法不是。重写抽象方法的方法必须是实打实方法。抽象方法不能有方法体。抽象方法不能有实现虚方法可以有实现哪怕是一个空的也必须有方法主题。可以做到与虚方法一样的结果。抽象类中也可以定义虚方法在普通类或其他类也可以实现。子类在抽象类中必须实现。abstruct叫抽象方法。隐式虚方法。抽象方法的方法体不是空的。重写抽象方法必须是实打实方法。抽象类通过派生类实例化调用派生类实例。如果派生类没有重写可以不重写调用基类中的方法。如果重写调用派生类中的方法。通过派生类中定义调用还是派生类中的方法。接口不管怎么做只管能做什么。类单继承利用接口可以实现多继承。不用I开头也支持。但可读性不强。接口主要是行为约定包含方法定义。接口主要定义方法接口不能直接实例化对象。抽象的不能实例化。接口是功能上的抽象。 语法合同是一个约定规定能做什么而不管怎么做需要实现的功能由派生类实现怎么做功能。接口用一个类实现接口哪怕抽象类也要实现。记住这个结构接口是功能上抽象定义接口实现接口。接口规定一系列能做什么而不能怎么做。派生类实现怎么做功能。接口好处体现封装具体暴露前端就是给他一个接口。供别人查看不暴露封装。定义一个Add方法好处**定义规则**一个接口可以继承另一个接口**抽象类也完全可以继承另一个抽象类或者普通类**。ShowInfo接口和Login接口一个接口继承另一个接口就具有另一个接口的方法。接口和抽象类区别方法定义都一样只能包含定义不能包含实现。接口和抽象类定义的方法都是抽象。 抽象类和接口都不能被实例化。都可以包含方法声明和方法定义。 派生类实现。抽象类抽象方法不能被实现非抽象类可以实现。接口主要定义方法进行方法声明。非抽象方法可以实现。一个类可以实现多个接口抽象类只能被单一一个类实现。抽象类只能被单一继承。一个是抽象方法定义一个是行为方法定义。行为特性就是接口。行为和特征抽象选择抽象类只注重行为选择接口。除非注重上不重视特征只重视行为抽象就是接口。抽象方法可以被实现非抽象方法不能被实现。一种是类抽象一种是功能抽象。同一命名空间类名必须唯一不同命名空间下可以有同名的。如果出现冲突性情况可以加上命名空间来解决冲突问题。如果类型引用报错和其他命名空间又没有其它相同名称冲突问题只需要引用命名空间就行。两个中一个显示一个引用命名空间名指代。遇到冲突没加会报错两个冲突问题不指代加上命名空间名。两个引用之一。多个命名空间有相同类名就这样清楚命名空间规范就可以**写全前缀**MySpace1.UserInfo→ 用的就是**前缀里的命名空间****不写前缀**UserInfo→ 用的就是**上面 using 引入的命名空间**异常处理保证程序运行中不会发生错误。有try后会跟catch或finally语句块跟一个或多个不中断程序在上层UI层调用层面捕获异常不抛下层不得不在调用方法内部去处理异常捕获到就直接处理向上抛的过程。try...catch可能会出现finallyexceptionex所有异常基类。执行最后逻辑finally 不管catch最后都会执行finallythrowUI层很少抛异常一般放在被调用的方法里面出现新的异常包装秤异常后往上抛针对性异常捕获做针对性异常处理。笼统性异常处理Exception处理 和针对性异常处理 分条针对性处理C#异常处理两种方式调用方法内部做异常捕获也不要做## 1. 直接抛就地抛出、就地处理在当前方法里**自己抛、自己抓**问题不往外传。### 代码示例public void Test(){try{int a 0;int res 10 / a;}catch{// 直接抛当前方法内部抛出throw;}}✅ 特点- 异常停在当前方法- 自己解决 / 自己触发崩溃- 简单粗暴不麻烦上层------## 三、2. 向上抛抛出给调用者、逐层上抛当前方法**不处理**把异常**抛给调用它的方法**交给上层处理。### 语法方法加 throws 思想C# 不用 throws靠 throw 往上丢// 本方法不捕获异常向上抛public void Test(){int a 0;int res 10 / a; // 出错自动向上抛}### 手动向上抛写法public void Test(){try{int a 0;int res 10 / a;}catch{// 向上抛交给调用我的人处理throw new Exception(运算出错);}}✅ 特点- 当前方法不背锅、不处理- 异常传递给**上层调用方**- 多层调用时一层层往上传------## 四、核心区别考试 / 面试必背| 类型 | 操作 | 处理方 | 适用场景 || :----- | :---------------- | :------- | :--------------------------------- || 直接抛 | throw; 本地抛出 | 当前方法 | 错误本地解决、直接终止 || 向上抛 | 抛给调用者 | 上层代码 | 底层方法只干活异常交给业务层处理 |------## 五、一句话绝杀记忆- **直接抛**自己犯错自己扛- **向上抛**自己不处理甩给上一级## 1. 直接抛就地抛出**自己捕获、自己扔、自己结束**try{// 出错代码}catch{throw; // 直接抛当前代码终止} 作用当前方法处理不了**当场报错**。------## 2. 向上抛抛出给调用方**下层不处理丢给上层方法处理**public void A(){B();}public void B(){// 出错不捕获自动向上抛给 A}手动向上抛catch{throw new Exception(错误); // 抛给调用我的方法}------## 核心口诀必背1. **直接抛**自己抓自己扔本地崩溃2. **向上抛**下层甩锅上层捕获处理