《C#从入门到放弃》
版本 | 作者 | 参与者 | 完成日期 | 备注 |
YanlzVR_C#_V01_1.0 | 严立钻 |
| 2020.04.25 |
|
|
|
|
|
|
##《C#从入门到放弃》发布说明:
++++“C#从入门到放弃”:是对“C#”的基础探索;【VR云游戏】:Unity+SteamVR+云技术+5G+AI:其中Unity主要开发语言就是C#,所以在进入Unity开发前先对C#进行一轮基础夯实;
++++“C#从入门到放弃”:定位在一个科普类知识,“从入门到放弃”是一个系列,是最基础的,也是最有参考价值的!
@@提示:有些博客可能只是开了头,如果感兴趣的同学,可以“点赞”或“评论区留言”,只要关注的同学多了,那就会继续完善哟!(“++==”,表示没有写完的,如果关注度不高就不完善了;“++ok++”,表示此篇博客已经完成,是阶段性完整的!)
$$$$博客溯源:
&&&&“从入门到放弃”系列:
++++【C#从入门到放弃】:
++++【Linux从入门到放弃】:
++++【C++从入门到放弃】:
++++【Python从入门到放弃】:
++++【Qt从入门到放弃】:
++++VR云游戏=Unity+SteamVR+云技术+5G+AI;(说明:AI人工智能不是我们的主要研究技术,只是了解一下,领略一下有风的感觉!但是,VR是我们的研究重点)
++++【Unity开发基础】分类:
++++【Linux系统编程】分类:
++++【C++C铸就生存利器】分类:
++++【人工智能AI2026】分类:
++++【立钻哥哥CSDN空间】:
##《C#从入门到放弃》目录
#第一篇:C#基础篇
#第二篇:C#提高篇
#第三篇:C#项目篇
#第四篇:C#在Unity中的应用篇
#第五篇:C#在游戏服务器应用篇
#第六篇:C#系统安全篇
#第七篇:立钻哥哥带您C#从入门到放弃
#第一篇:C#基础篇
#第一篇:C#基础篇 |
#第一篇:C#基础篇
++++立钻哥哥:C#是微软公司发布的一种简洁的、面向对象的且类型安全的程序设计语言;C#应用领域比较广泛,可以进行游戏软件开发、桌面应用系统开发、智能手机程序开发、多媒体系统开发、网络应用程序开发以及操作系统平台开发等;因C#语言简单易学,功能强大,所以受到很多程序员的青睐,成为程序开发人员使用的主流编程语言之一;
++1.1、基本数据类型
++1.2、分支结构
++1.3、C#循环和一维数组
++1.4、C#二维数组
++1.5、枚举与结构体
++1.6、类和面向对象编程
++1.7、属性、引用数据类型和方法参数
++1.8、字符串、方法的重载和递归
++1.9、C#面向对象
++1.10、抽象类,静态类与单例
++1.11、接口与泛型
++1.12、C#集合
++1.13、C#委托
++1.14、程序设计6大原则
++1.15、23种设计模式
##1.1、基本数据类型
##1.1、基本数据类型 |
++1.1、基本数据类型
++++1.1.1、先来了解一下C#
++++1.1.2、一个简单的程序分析HelloWorld
++++1.1.3、基本数据类型
++++1.1.4、常量、变量、运算符、表达式、语句
++++1.1.5、基本输入、输出函数
++++1.1.6、类型转换
####1.1.1、先来了解一下C#
++++1.1.1、先来了解一下C# |
++1.1.1、先来了解一下C#
++++立钻哥哥:C#是微软公司发布的一种面向对象的、安全的、稳定的、简单的、优雅的编程语言;
++Unity使用C#开发
++++立钻哥哥:Unity3D引擎就是用C#开发的,所以熟悉C#非常重要;
主流引擎 | 主流开发语言 | 其他 |
Unity3D | C# | Boo、UnityScript已弃用 |
虚幻4 | C++ | 大型游戏开发 |
Cocos2dx | C++、Lua、JavaScript | 主要是2D游戏开发 |
###1.1.2、一个简单的程序分析HelloWorld
###1.1.2、一个简单的程序分析HelloWorld |
++1.1.2、一个简单的程序分析HelloWorld
++++立钻哥哥:
using System;
namespace MyHelloWorld{ class MainClass{ public static void Main(string[] args){ Console.Write(“立钻哥哥:Hello World!”); } } } |
###1.1.3、基本数据类型
###1.1.3、基本数据类型 |
++1.1.3、基本数据类型
++++立钻哥哥:
关键字 | 字节大小 | 说明 |
bool | 1字节 | 逻辑真(真/假) |
btye | 1字节 | 无符号8位整数 |
char | 2字节 | 16位字符类型 |
short | 2字节 | 有符号16位整数 |
int | 4字节 | 有符号32位整数 |
float | 4字节 | 32位单精度浮点类型 |
double | 8字节 | 64位双精度浮点类型 |
long | 8字节 | 有符号64位整数 |
###1.1.4、常量、变量、运算符、表达式、语句
###1.1.4、常量、变量、运算符、表达式、语句 |
++1.1.4、常量、变量、运算符、表达式、语句
++++立钻哥哥:
++++[常量]:程序运行期间,不能被改变的量;
++++[变量]:程序运行期间,可以被改变的量;
++++[变量定义]:类型修饰符 变量名 = 初始值;(string name = “立钻哥哥”;)
++++[运算符]:赋值运算符(“=”),算术运算符(“+、-、*、/”等);
++++[表达式]:由常量、变量与运算符组成;
++++[语句]:语句是程序执行的最小单位,以分号结尾;
###1.1.5、基本输入、输出函数
###1.1.5、基本输入、输出函数 |
++1.1.5、基本输入、输出函数
++++立钻哥哥:System.Console类;
++++[输出函数]:Console.WriteLine(“立钻哥哥:Hello World!”);
++++[输入函数]:Console.Read();/Console.ReadLine();
###1.1.6、类型转换
###1.1.6、类型转换 |
++1.1.6、类型转换
++++立钻哥哥:类型转换分为:隐式转换、强制转换;
++++[隐式转换]:由小到大转换时系统会自动的进行隐式转换;
++++[强制转换]:由大变小转换时要用强制转换;(会缺失精度)
##1.2、分支结构
##1.2、分支结构 |
++1.2、分支结构
++++1.2.1、bool布尔类型
++++1.2.2、关系运算符
++++1.2.3、逻辑运算符
++++1.2.4、if语句
++++1.2.5、switch语句
###1.2.1、bool布尔类型
###1.2.1、bool布尔类型 |
++1.2.1、bool布尔类型
++++立钻哥哥:布尔类型的变量只有true和false两个值;
bool isBoy = true;
if(isBoy){ Console.Write(“男孩喜欢妹子”); }else{ Console.Write(“美女喜欢买包包,包治百病!”); } |
###1.2.2、关系运算符
###1.2.2、关系运算符 |
++1.2.2、关系运算符
++++立钻哥哥:常用的关系运算符有:>、<、>=、<=、==、!=等;
###1.2.3、逻辑运算符
###1.2.3、逻辑运算符 |
++1.2.3、逻辑运算符
++++立钻哥哥:常用的逻辑运算符有:&&(逻辑与)、||(逻辑或)、!(逻辑非);
###1.2.4、if语句
###1.2.4、if语句 |
++1.2.4、if语句
++++立钻哥哥:if语句属于分支结构;
++++[if语句第一种形式]:if(条件表达式){ 语句1; }
++++[if语句第二种形式]:if(条件表达式){ 语句1; }else{ 语句2; }
++++[if语句第三种形式]:
if(条件表达式1){ 语句1; }else if(条件表达式2){ 语句2; }else{ 语句3; } |
###1.2.5、switch语句
###1.2.5、switch语句 |
++1.2.5、switch语句
++++立钻哥哥:多分支语句,通过判断表达式的值,来决定执行哪个分支;
++++[switch通常与case配合使用]:switch开关;case情况;
switch(表达式){ case 值1: { 语句1; break; } case 值2: { 语句2; break; } ... case 值n: { 语句n; break; } default:{ 语句n+1; break; } } |
++++提示1:switch(表达式)里面的表达式类型不能是浮点类型;
++++提示2:case后面只要有操作,最后一定要加break;
##1.3、C#循环和一维数组
##1.3、C#循环和一维数组 |
++1.3、C#循环和一维数组
++++1.3.1、循环结构
++++1.3.2、一维数组
###1.3.1、循环结构
###1.3.1、循环结构 |
++1.3.1、循环结构
++++立钻哥哥:循环结构是在满足某个条件的时候反复执行一个语句序列(循环);
++++[三种循环结构]:while循环;do-while循环;for循环;
++++[break]:跳出本层循环;
++++[continue]:结束本次循环;
++while循环
++++立钻哥哥:条件表达式为真,执行循环体;一旦条件表达式为假,循环停止;
while(bool表达式){ 循环体; } |
++do..while循环
++++立钻哥哥:先执行循环体,再判断循环条件,直到条件不满足的时候,循环结束;
do{ 循环体; }while(条件表达式); |
++for循环
++++立钻哥哥:循环条件为真,执行循环体;
for(循环变量初始化; 循环条件; 循环增量){ 循环体; } |
###1.3.2、一维数组
###1.3.2、一维数组 |
++1.3.2、一维数组
++++立钻哥哥:数组用来存储相同类型的数据;每个成员称为一个数组元素;
++++数组定义:int[] number; float[] scores; string[] names;
++动态初始化
++++立钻哥哥:借助new运算符为数组元素分配内存空间,并赋初值;
int[] intArray = new int[6]; int[] intArray = new int[3]{ 1, 2, 3 }; int[] intArray = new int[]{ 1, 2, 3 }; |
++静态初始化
++++立钻哥哥: 数据类型[] 数组名 = { 元素1, 元素2, ..., 元素n };
int[] myArr = { 1, 2, 3, 4, 5}; |
##1.4、C#二维数组
##1.4、C#二维数组 |
++1.4、C#二维数组
++++1.4.1、冒泡排序
++++1.4.2、选择排序
++++1.4.3、二分查找
++++1.4.4、二维数组
++++1.4.5、foreach循环
###1.4.1、冒泡排序
++1.4.1、冒泡排序
++++立钻哥哥:冒泡排序算法原理:比较相邻的元素,如果第一个比第二个大,就交换它们两个;
for(int i = 0; i < nums.Length - 1; i++){ for(int j = 0; j < nums.Length - 1 - i; j++){ if(nums[j] > nums[j+1]){ int temp = nums[j]; nums[j] = nums[j + 1]; nums[j + 1] = temp; } } } |
##1.5、枚举与结构体
##1.5、枚举与结构体 |
++1.5、枚举与结构体
++++1.5.1、枚举
++++1.5.2、结构体
++++1.5.3、访问修饰符
###1.5.1、枚举
###1.5.1、枚举 |
++1.5.1、枚举
++++立钻哥哥:枚举类型:定义了一组可以赋值给变量的命名整数常量提供了一种有效方法,枚举是一种值类型;
++++[格式]:enum 枚举名{ 枚举数0, 枚举数1, ... }
++++例如:enum Season{ Spring, Summer, Autumn, Winter }
###1.5.2、结构体
###1.5.2、结构体 |
++1.5.2、结构体
++++立钻哥哥:结构体是一种值类型,通常用来封装小型相关变量组;
++++结构体是一种自定义的数据类型,相当于一个复合容器,可以存储多种类型;
++++结构体由结构体成员构成:包含字段,属性与方法;
++++[格式]:struct 结构体名{ 结构体成员 }
struct Weapon{ public string name; public int physicalDefense; public int maxHp; } |
++++提示:字段不能有初始值,只能声明;
###1.5.3、访问修饰符
###1.5.3、访问修饰符 |
++1.5.3、访问修饰符
++++立钻哥哥:访问修饰符:所有类型和类型成员都具有可访问性级别;
++常用访问修饰符
++++[public]:同一程序集中的任何其他代码或引用该程序集的其他程序集都可以访问该类型或成员;
++++[private]:只有同一类或结构中的代码可以访问该类型或成员;
++++[protected]:只有同一类或结构或者此类的派生类中的代码才可以访问的类型或成员;
##1.6、类和面向对象编程
##1.6、类和面向对象编程 |
++1.6、类和面向对象编程
++++1.6.1、面向对象
++++1.6.2、类
++++1.6.3、对象
++++1.6.4、字段
++++1.6.5、方法
###1.6.1、面向对象
###1.6.1、面向对象 |
++1.6.1、面向对象
++++立钻哥哥:[面向过程]VS[面向对象];
++[面向过程]
++++立钻哥哥:面向过程是以事件为中心,强调的是完成某一件事情需要哪些步骤以及步骤的先后顺序;
++++比如:把大象放进冰箱,总共分为三步:
--第一步:把冰箱门打开;
--第二步:把大象放进冰箱;
--第三步:关上冰箱门;
++++代表语言:C语言;
++[面向对象]
++++立钻哥哥:面向对象以对象为中心,强调完成某一件事情需要哪些对象相互协作来完成,参与该事情的对象需要具备哪些功能; 该事件也是所有事件当中的某一小功能;
++++比如:将大象放进冰箱强调事物的参与者:就是 冰箱与大象;
++++代表语言:C++、C#、Java等;
###1.6.2、类
###1.6.2、类 |
++1.6.2、类
++++立钻哥哥:类是描述具有相同特征与行为的事物的抽象;
++++类是一种构造,通过该构造可以将不同类型的变量,方法组合在一起创建出自定义类型;
++++类是面向对象程序设计实现信息封装的基础;
++类的声明
++++立钻哥哥:class关键字用于类的声明;
++++[格式]: 访问修饰符 class 类名{ 类成员变量 }
namespace YanlzFramework{ public class MyClass{ } } |
###1.6.3、对象
###1.6.3、对象 |
++1.6.3、对象
++++立钻哥哥:对象是类的具体实例,万事万物皆对象;
++++类是对象的类型;
++对象的创建
++++立钻哥哥:对象的创建使用new关键字;
++++[格式]: 类名 对象名 = new 类名();
MyHero hero = new MyHero(); |
###1.6.4、字段
###1.6.4、字段 |
++1.6.4、字段
++++立钻哥哥:字段是用来描述类的特征的;
++++[格式]: 访问修饰符 字段类型 字段名;
++++[声明并初始化]: 访问修饰符 字段类型 字段名 = 初始值;
class MyHero{ public string name; public int HP; public string type; } |
++字段的使用
++++立钻哥哥:字段的使用要通过对象: 对象.字段;
MyHero hero = new MyHero(); hero.name = “立钻哥哥”; hero.HP = 9999; hero.type = “坦克”; |
###1.6.5、方法
###1.6.5、方法 |
++1.6.5、方法
++++立钻哥哥:方法是用来描述类当中的行为的;
++++方法就是封装了一段有特定功能的代码段,是对象用来实现某个功能的;
++++方法是用来描述类的行为的;(字段是用来描述类的特征的)
##1.7、属性、引用数据类型和方法参数
##1.7、属性、引用数据类型和方法参数 |
++1.7、属性、引用数据类型和方法参数
++++1.7.1、属性
++++1.7.2、引用数据类型
++++1.7.3、方法参数
###1.7.1、属性
###1.7.1、属性 |
++1.7.1、属性
++++立钻哥哥:属性提供灵活的机制来读取、编写或计算某个私有字段的值;
++++属性(访问器)本质上也是Get和Set方法,只是在形式上不同;
class MyHero{ private string name; public int Name{ get{ return name; } set{ name = value; } } } |
++++属性的简写方式: public string Name{ get; set; }
###1.7.2、引用数据类型
###1.7.2、引用数据类型 |
++1.7.2、引用数据类型
++++立钻哥哥:引用类型在堆中分配空间,由程序员用“new”来分配空间;
++++引用类型包括:Object、string、类、接口、委托、数组等;
++++C#中两种数据类型: 引用类型 和 值类型;
###1.7.3、方法参数
###1.7.3、方法参数 |
++1.7.3、方法参数
++++立钻哥哥:方法参数有 形式参数(形参) 和 实际参数(实参);
class MyMath{ //形式参数(形参) public void Swap(ref int x, ref int y){ int temp = x; x = y; y = temp; } } |
MyMath myMath = new MyMath(); int scoreA = 80; int scoreB = 100;
//实际参数(实参) myMath.Swap(scoreA, scoreB); |
++引用参数
++++立钻哥哥:值类型参数要想达到引用类型参数的效果,需要用到引用参数;
++++引用参数用 ref修饰符声明;
++++注意: ref修饰的变量在传递参数前一定要有初始值;
++输出参数(out)
++++立钻哥哥:如果想要一个方法返回多个值,可以用输出参数来处理;
++++输出参数由 out关键字标识;
public void Calculate(int a, int b, out int x, out int y){ x = a - b; y = a + b; } |
++++注意1:在方法中out修饰的参数必须先初始值,才能使用;
++++注意2:out修饰的变量在传递前,可以没有初始值;
++数组参数(params)
++++立钻哥哥:
public void Sum(parmas int[] a){ int result = 0; foreach(int x in a){ result += x; }
Console.WriteLine(“立钻哥哥:结果为 ” + result); } |
myMath.Sum(1, 2, 3, 4, 5, 6); |
++++params数组参数的注意点:
--1、params参数的长度可变;长度可以为0;
--2、只能使用一次,而且要放到最后;
--3、数组类型不能跟 ref、out一起搭配使用;
++C#中方法的4种参数类型
++++[值类型]:不附加任何修饰符;
++++[输出参数]: 以out修饰符声明,可返回一个或多个值给调用者;
++++[引用参数]: 以ref修饰符声明;
++++[数组参数]: 以params修饰符声明;
##1.8、字符串、方法的重载和递归
##1.8、字符串、方法的重载和递归 |
++1.8、字符串、方法的重载和递归
++++1.8.1、string字符串
++++1.8.2、StringBuilder类
++++1.8.3、重载
++++1.8.4、递归
###1.8.1、string字符串
###1.8.1、string字符串 |
++1.8.1、string字符串
++++立钻哥哥:System.String类是以一个专门存放字符串的类,允许字符串进行许多操作;
方法 | 作用 |
Format | 格式化包含各种值的字符串和如何格式化每个值的说明符 |
Insert | 把一个字符串实例插入到另一个字符串实例的指定索引处 |
Replace | 用另一个字符或子字符串替换字符串中给定的字符或子字符串 |
ToLower | 把字符串转换为小写形式 |
ToUpper | 把字符串转换为大写形式 |
###1.8.2、StringBuilder类
###1.8.2、StringBuilder类 |
++1.8.2、StringBuilder类
++++立钻哥哥:StringBuilder类通常分配的内存会比它需要的多,对字符串的修改就在赋予StringBuilder实例的内存中进行,这就大大提高了追加子字符串和替换单个字符的效率;
###1.8.3、重载
###1.8.3、重载 |
++1.8.3、重载
++++立钻哥哥:方法重载是指在同一个类中方法同名,参数不同,调用时根据实参的形式,选择与他匹配的方法执行操作的一种技术;
++++重载主要是参数不同:类型不同;个数不同;顺序不同;(返回值不同不能构成重载)
###1.8.4、递归
###1.8.4、递归 |
++1.8.4、递归
++++立钻哥哥:递归:函数体内调用本函数自身,直到符合某一条件不再继续调用;
++递归满足的条件
++++条件1:有反复执行的过程(调用自身)
++++条件2:有跳出反复执行过程的条件(函数出口)
//斐波那切数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ... public static int MyFibonacci(int n){ if(n < 0){ return -1; } if(0 == n){ return 0; } if(1 == n){ return 1; }
return MyFibonacci(n - 1) + MyFibonacci(n - 2); } |
##1.9、C#面向对象
##1.9、C#面向对象 |
++1.9、C#面向对象
++++1.9.1、构造函数
++++1.9.2、面向对象程序设计
++++1.9.3、面向对象的三大特征
###1.9.1、构造函数
###1.9.1、构造函数 |
++1.9.1、构造函数
++++立钻哥哥:构造函数的作用就是创建类或结构的实例,在实例化对象的时候,也就是new MyClass()时调用;
++++构造函数可以快速的构建对象,在构造函数中做些初始化字段的功能;
class MyPerson{ public string name; pubic int age;
public MyPerson(){ } } ++++构造函数(方法)必须与类重名; ++++构造函数没有返回值,但可以有形参; ++++构造函数可以有重载;
|
//带有参数的构造函数 public MyPerson(string name, int age){ this.name = name; this.age = age; }
|
//构造函数实例化对象 MyPerson p1 = new MyPerson(); MyPerson p2 = new MyPerson(“成龙大哥”, 56); |
###1.9.2、面向对象程序设计
###1.9.2、面向对象程序设计 |
++1.9.2、面向对象程序设计
++++立钻哥哥:面向对象是为了解决系统的可维护性,可扩展性,可重用性;
++++面向对象是把构成问题事物分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描述某个事物在整个解决问题步骤中的行为;
###1.9.3、面向对象的三大特征
###1.9.3、面向对象的三大特征 |
++1.9.3、面向对象的三大特征
++++立钻哥哥:面向对象的三大特征:封装、继承、多态;
++[封装]
++++立钻哥哥:封装就是将数据或函数等集合在一个个的类中;
++++封装是实现面向对象程序设计的第一步,找到变化并且把它封装起来,可以在不影响其他部分的情况下修改或扩展被封装的变化部分,这是所有设计模式的基础,就是封装变化,因此封装的作用,就解决了程序的可扩展性;
++++属性的出现就是为了保护字段不被外部恶意破坏,这就是封装:
class MyPerson{ private string name; public string Name{ get{ return name; } set{ this.name = value; } } } |
++[继承]
++++立钻哥哥:继承用于创建可重用,扩展和修改在其他类中定义的行为的新类;
++++被继承的类称为“基类”,继承这些成员的类称为“派生类”;
++[多态]
++++立钻哥哥:父类指针指向子类对象;
++++多态指同一个实体同时具有多种形式;
++++基类的需方法用virtual修饰,子类重写时使用override;
##1.10、抽象类,静态类与单例
##1.10、抽象类,静态类与单例 |
++1.10、抽象类,静态类与单例
++++1.10.1、抽象类
++++1.10.2、静态类
++++1.10.3、单例
###1.10.1、抽象类
###1.10.1、抽象类 |
++1.10.1、抽象类
++++立钻哥哥:抽象方法是指只有方法的声明而没有具体实现的方法;
++++抽象方法使用关键字abstract修饰,这种方法只能声明返回值类型,方法名以及参数列表,没有方法体;
++++当一个类中存在抽象方法时,该类必须也使用abstract修饰,就成了抽象类;
abstract class MyPlayer{ public abstract void Practice(); } |
++++抽象方法的访问修饰符不能为private,因为抽象方法必须被派生类重写,派生类必须能够访问到;
++++利用abstract关键字可以将方法声明抽象到父类当中,而方法的实现留在子类,更好的体现“共性放在父类”的原则;
++抽象方法特性:
++++1、抽象方法是隐式的虚方法;
++++2、抽象方法只能有声明不提供实际的实现;
++++3、抽象方法必须被子类重写并实现,否则其子类依旧为抽象类;
++++4、抽象方法不使用static或virtual修饰;
++抽象类的特性:
++++1、抽象类不能使用new关键字进行实例化,抽象类是不完整的,只能作为基类被其他类继承;
++++2、抽象类除了可以拥有普通类成员外还可以有抽象方法;
++++3、从抽象类派生的非抽象类必须实现抽象类当中的所有抽象方法;
++++4、抽象类不能被实例化但可以有构造方法,构造方法不能为抽象方法;
++++5、不能使用sealed修饰符修饰抽象类,因为采用sealed修饰符的类是无法被继承的,而抽象类是必须被继承的;
###1.10.2、静态类
###1.10.2、静态类 |
++1.10.2、静态类
++++立钻哥哥:静态类用于创建无需创建类的实例就能访问的数据和函数,静态类只能包含静态成员,不可以包含非静态成员;
++++静态成员用于分离独立任何对象标识的数据和行为:无论对象发生任何改变,这些数据和函数都不会随之变化;
++++静态类使用static关键字修饰;
//数学运算不依赖任何对象,可以将其定义为静态类 static class Mathf(){ public static string mainFunc = “简单数学运算”; public const int defaultValue = 0; //可以定义const修饰的常量
//求绝对值 public static int MyAbs(int value){ return value > 0 ? value : -value; }
//求两个整数当中的最小值 public static int MyMinValue(int numA, int numB){ return numA > numB ? numB : numA; } } |
++++访问静态类中的成员使用类名加点操作加静态成员的方式:
int absValue = Mathf.MyAbs(-10); int minValue = Mathf.MyMinValue(20,30); |
++静态类特性
++++1、静态类只能包含静态成员,不能包含非静态成员;
++++2、静态类无法实例化;
++++3、静态类是密封的,无法被继承;
++++4、静态不能包含有实例构造函数;
++静态构造函数
++++立钻哥哥:静态类不能有实例化构造函数,但是可以有静态构造函数;
++++静态构造函数用于初始化任何静态数据或用于执行仅需要执行一次的特定操作;
static 类名(){ //初始化静态数据或执行其他操作 } |
++++静态构造函数可以出现在非静态类当中,在非静态类中除了可以声明实例构造函数,也可以声明静态构造函数:
class MyHero{ //实例构造函数 public MyHero(string name, int HP, string type){ this.name = name; this.HP = HP; this.type = type; }
//静态构造函数 static MyHero(){ } } |
++++静态构造函数无法像实例构造函数那样通过某一个关键字调用;静态构造函数不可被直接调用,当创建类实例或引用任何静态成员之前,静态构造函数会被调用;
++静态构造函数的特性
++++1、静态构造函数是固定格式,不能有修饰符,不能带任何参数;
++++2、一个类只能有一个静态构造函数,即静态构造函数不可以重载;
++++3、静态构造函数不可被直接调用,当创建类实例或引用任何静态成员之前,静态构造函数会被自动调用,并且只执行一次;
++++4、一个类的静态构造函数在它的所有派生类的静态构造函数执行之后执行;
++静态成员
++++立钻哥哥:静态成员变量是和类相关联的,可以作为类中“共”有的变量(是一个共性的表现),静态成员不依赖特定对象的存在,访问的时候通过类来操作的;
++++静态成员使用static关键字修饰;
public class MyDog{ public static string type = “MyDog”;
public static void WatchDoor(){ Console.WriteLine(“小狗会看门”); } } |
++++访问静态成员采用类名加点操作加静态成员:
MyDog.WatchDoor(); |
++静态成员的特点
++++1、静态成员随着类的加载而加载,无论一个类创建多少个实例,静态成员都只有一个副本;
++++2、静态方法可以被重载但不能被重写,因为他们是属于类,不属于任何的实例;
++++3、静态成员由类名通过点语法调用,非静态成员是由对象来调用;
++++4、静态方法只能访问静态成员,包括静态成员变量和静态方法;实例方法可以访问实例成员变量与实例方法,也可以访问静态成员;
###1.10.3、单例
###1.10.3、单例 |
++1.10.3、单例
++++立钻哥哥:设计模式是一套被反复使用,多数人知晓,经过分类,代码设计经验的总结;
++++常用的设计模式有:单例模式,工厂模式,代理模式;
++单例模式的三要素
++++1、单例只能有一个实例;
++++2、单例必须自行创建这个实例;
++++3、单例必须自行向外界提供这个实例;
public class MySingleton{ private MySingleton(){} //构造方法必须私有化 private static MySingleton instance; //定义静态实例
//静态构造函数中对静态实例进行初始化 static MySingleton(){ instance = new MySingleton(); }
//对外提供获取该实例的接口 public static MySingleton Instance{ get{ if(null == instance){ instance = new MySingleton(); }
return instance; } }
} |
++单例的作用
++++立钻哥哥:单例模式是资源管理的必备模式,单例类只有一个实例对象,因此可以通过该实例对象获取到管理的资源;
++++单例模式会阻止其他对象实例化,从而确保所有对象都访问唯一实例;
++++单例类能够节省大量创建对象的过程,从而节省内存开销;
##1.11、接口与泛型
##1.11、接口与泛型 |
++1.11、接口与泛型
++++1.11.1、接口
++++1.11.2、泛型
###1.11.1、接口
###1.11.1、接口 |
++1.11.1、接口
++++立钻哥哥:接口是一组包含了类或结构可以实现的功能的定义;
++++C#只支持单继承,所以接口支持多实现的特性可以在一定程度上弥补该不足;
++++[格式]:访问修饰符 interface 接口名{ 接口成员 }
++++通过interface关键字定义接口:
public interface IFly{ void MyFly(); }
public interface ISpeak{ void MySpeak(); } |
++接口的特性
++++1、接口是一个引用类型,只包含了功能的定义,不包含功能的实现;
++++2、C#接口成员的访问级别是默认的(默认为public),不可以使用其他修饰符修饰;
++++3、C#接口成员不能有static、abstract、override、virtual修饰;
++++4、接口一旦被实现,就必须实现接口当中的所有成员,除非实现类本身是抽象类;
++++5、接口无法直接进行实例化,因为其成员必须通过由实现接口的任何类或结构来实现;
++++6、接口可以包含事件,索引器,方法和属性,但是不能包含字段;
++++7、类的继承只能单继承,接口的实现支持多实现;
++接口的实现
++++立钻哥哥:接口中方法的定义不允许加上访问修饰符,默认修饰符为public;
class Parrot : IFly, ISpeak{ public void MySpeak(){ Console.WriteLine(“鹦鹉会说话”); }
public void MyFly(){ Console.WriteLine(“鹦鹉会飞”); } } |
++++类实现接口就必须实现接口当中定义的所有方法,除非该类是抽象类;
++接口与抽象类
++++立钻哥哥:接口和抽象类非常相似,它定义了一些未实现的属性和方法;所有继承接口的类都继承这些成员,在这个角度上,可以把接口理解为一个类的模板;
++++接口最终的目的是起到统一的作用;
++++相同点:
--1、两者都不能被实例化;
--2、两者都包含了由其他类或结构继承或实现的抽象成员;
++++不同点:
--1、抽象类当中除了拥有抽象成员外还可以拥有非抽象成员;而接口中所有的成员都是抽象的;
--2、抽象类成员可以使用修饰符修饰;接口当中接口成员访问级别是默认public;
--3、接口当中不可以包含构造方法,析构方法,静态成员以及常量;
--4、C#类只支持单继承;接口支持多继承;
###1.11.2、泛型
###1.11.2、泛型 |
++1.11.2、泛型
++++立钻哥哥:C#中的泛型能够将类型作为参数来传递,即在创建类型时用一个特定额符号如“T”来作为一个占位符,代替实际的类型,等待在实例化时再用一个实际的类型来代替;
public static void Swap<T>(ref T value1, ref T value2){ T temp = value1; value1 = value2; value2 = temp; } |
++泛型的优点
++++1、使用泛型可以重用代码,保护类型的安全以及提高性能;
++++2、降低强制转换或装箱操作的成本和风险;
++++3、可以对泛型参数进行限定以访问特定数据类型的方法;
++泛型类型参数常用的约束类型
++++立钻哥哥:
类型 | 含义 |
where T : struct | 表示泛型T是值类型(小数、整数、char、bool、struct) |
where T : class | 表示泛型T是引用类型 |
where T : new() | 表示这个泛型具有一个无参数的构造方法,如果有多个约束,new()必须放在最后 |
where T : 基类名 | 表示这个泛型是该基类或者其派生类 |
where T : 接口名 | 表示泛型是实现了该接口的类型 |
##1.12、C#集合
##1.12、C#集合 |
++1.12、C#集合
++++1.12.1、数组的局限性
++++1.12.2、集合的概念
++++1.12.3、常见的集合
++++1.12.4、集合的类成员与用法
###1.12.1、数组的局限性
###1.12.1、数组的局限性 |
++1.12.1、数组的局限性
++++立钻哥哥:数组只能存储相同类型的数据;
++++数组不能动态的扩展长度(会出现数组越界);
int[] intArray = new int[3]; intArray[4] = 99; //数组越界 |
###1.12.2、集合的概念
###1.12.2、集合的概念 |
++1.12.2、集合的概念
++++立钻哥哥:集合好比容器,将一系列相似的对象组合在一起,是一个特殊的类,和数组一样,可以通过索引访问集合成员,也可以通过“键”来访问;
++++与传统数组不同的是:集合的大小可以动态调整,可以在运行时添加或删除元素;
++集合的类型
++++立钻哥哥:集合分为:泛型集合与非泛型集合;
++++[非泛型集合]:位于System.Collections命名空间;
++++[泛型集合]:位于System.Collections.Generic命名空间;
###1.12.3、常见的集合
###1.12.3、常见的集合 |
++1.12.3、常见的集合
++++立钻哥哥:
++++[非泛型集合(System.Collections)]:ArrayList(动态数组);Stack(堆栈);Queue(队列);Hash Table(哈希表);
++++[泛型集合(System.Collections.Generic)]:List<T>、Stack<T>、Queue<T>、Dictionary<TKey, Tvalue>;
###1.12.4、集合的类成员与用法
###1.12.4、集合的类成员与用法 |
++1.12.4、集合的类成员与用法
++++立钻哥哥:ArrayList(动态数组);List<T>(泛型动态数组);Stack(堆栈);Queue(队列);HashTable(哈希表);Dictionary<TKey, Tvalue>(字典);
++ArrayList(动态数组)
++++立钻哥哥:不安全的集合类型;
++++其元素为值类型时,效率不高(装箱和拆箱耗性能);
++++常用方法:Add(); Insert(); Remove(); Reverse(); Contains(); Clear();
++List<T>(泛型动态数组)
++++立钻哥哥:List类是ArrayList类的泛型等效类;(安全的集合类型)
++++与ArrayList不同的是,声明集合时需要声明集合内部的数据类型,即T的类型;
++++常用方法:Add(); Insert(); Remove(); Reverse(); Contains(); Clear(); IndexOf(T);
++Stack(堆栈)
++++立钻哥哥:后进先出(LIFO)的一种数据结构,本质上堆栈也是一种线性结构;
++++不安全的数据结构,其泛型为Stack<T>;
++++常用方法:Push(); Pop(); Peek(); Contains(); Clear(); Count;
++Queue(队列)
++++立钻哥哥:先进先出(FIFO)的一种数据结构;
++++不安全的数据结构,其泛型为Queue<T>;
++++常用方法:Enqueue(); Dequeue(); Peek(); Contains(); Clear(); Count;
++HashTable(哈希表)
++++立钻哥哥:处理和表现类似key-value的键值对的集合;
++++Key值必须唯一,区分大小写;Value可以是变量,也可以是对象;
++++常用方法:Add(); Clear(); ContainsKey(); ContainsValue(); Remove(); Keys(); Values();
++Dictionary<TKey, Tvalue>(字典)
++++立钻哥哥:同哈希表一样,根据键进行的键值对的集合,不同的是对键值进行了类型限定;
++++常用方法:Add(); Clear(); ContainsKey(); ContainsValue(); Remove(); Keys(); Values();
##1.13、C#委托
##1.13、C#委托 |
++1.13、C#委托
++++1.13.1、什么是委托?
++++1.13.2、委托的声明&匿名函数
++++1.13.3、系统委托&Lambda表达式
++++1.13.4、事件的由来
++++1.13.5、事件和委托有什么区别
###1.13.1、什么是委托?
###1.13.1、什么是委托? |
++1.13.1、什么是委托?
++++立钻哥哥:委托(delegate)是表示将 方法作为参数传递 给其他方法;
++++委托(delegate)类似函数指针,委托是面向对象的,类型安全的;委托既能引用静态方法,也能引用实例方法;
++++委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用“if-else(switch)”语句,同时使得程序具有更好的可扩展性;
###1.13.2、委托的声明&匿名函数
###1.13.2、委托的声明&匿名函数 |
++1.13.2、委托的声明&匿名函数
++++立钻哥哥:
class HelloWorld{ //声明委托 public delegate void GreetingDelegate(string name); }
|
public void GreetingPeople(string name, GreetingDelegate method){ //委托的调用方法同方法调用一样 method(name); } |
++匿名函数
++++立钻哥哥:匿名函数的出现就是在初始化时内联声明的方法,使得委托的语法更简洁;
MyClick click = delegate(){ Console.WriteLine(“立钻哥哥:按钮被点击了”); }; click(); |
###1.13.3、系统委托&Lambda表达式
###1.13.3、系统委托&Lambda表达式 |
++1.13.3、系统委托&Lamaba表达式
++++立钻哥哥:C#中内置了三种委托方式:Func委托;Action委托;Predicate委托;
++++[Func委托]:delegate TResult Func<TResult>;(Func委托必须带有返回值)
++++[Action委托]:delegate void Action(); (Action委托没有返回值)
++++[Predicate委托]:用的比较少;
++++提示:有返回值选择Func委托;没有返回值选择Action委托;
++Lambda表达式
++++立钻哥哥:Lambda表达式是一个匿名函数,是一种高效的类似于函数式编程的表达式;
++++Lambda运算符的左边是输入参数(如果有),右边是表达式或语句块;
delegate1 d1 = (x) => {}; delegate2 d2 = (x, y) => { return x + y; }; |
###1.13.4、事件的由来
###1.13.4、事件的由来 |
++1.13.4、事件的由来
++++立钻哥哥:事件是说在发生其他类或对象关注的事情时,类或对象可通过事件通知它们;
++++事件的关键字是:event;
++++event封装了委托类型的变量: 在类的内部,不管声明是public还是protected,它总是private的;在类的外部,注册”+=”和注销“-=”;
++++声明一个事件(event)类似于声明一个进行了封装的委托类型(delegate)的变量;
public delegate void CatShoutEventHandler(); public event CatShoutEventHandler CatShout; |
###1.13.5、事件和委托有什么区别
###1.13.5、事件和委托有什么区别 |
++1.13.5、事件和委托有什么区别
++++立钻哥哥:事件是一种特殊的委托的实例,或者说是受限制的委托,是委托的一种特殊应用;在类的外部只能施加+=,-=操作符;二者本质上是一个东西;
++++事件只允许用add(+=),remove(-=)方法来操作,这导致了它不允许在类的外部被直接触发,只能在类的内部适合的时机触发;委托可以在外部被触发,但是别这么用;
++++使用中,委托常用来表示回调,事件表达外发的接口;
++++事件不可以当作形参传递,但是委托可以;
##1.14、程序设计6大原则
##1.14、程序设计6大原则 |
++1.14、程序设计6大原则
++++立钻哥哥:6大设计原则:单一职责原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特法则、开放封闭原则;
++++Single Responsibility Principle: 单一职责原则;
++++Open Closed Principle: 开闭原则;
++++Liskov Substitution Principle: 里氏替换原则;
++++Law of Demeter: 迪米特法则;
++++Interface Segregation Principle: 接口隔离原则;
++++Dependence Inversion Principle: 依赖倒置原则;
====>S、O、L、L、I、D:SOLID(solid,稳定的):建立稳定、灵活、健壮的设计;
##1.15、23种设计模式
##1.15、23种设计模式 |
++1.15、23种设计模式
++++立钻哥哥:23种设计模式:单例模式;工厂方法模式;抽象工厂模式;建造者模式;原型模式;适配器模式;装饰模式;桥接模式;组合模式;享元模式;代理模式;外观模式;观察者模式;模板方法模式;命令模式;状态模式;职责链模式;解释器模式;中介者模式;访问者模式;策略模式;备忘录模式;迭代器模式;
++单例模式(Singleton)
++++立钻哥哥:单例模式(Singleton)保证一个类仅有一个实例,并提供一个访问它的全局访问点;
class Singleton{ private static Singleton instance; private Singleton(){} //构造方法让其private,防止外界利用new实例化
//此方法是获得本类实例的唯一全局访问点 public static Singleton GetInstance(){ if(null == instance){ instance = new Singleton(); //不存在,new实例化一个 }
return instance; } } |