C#基础第一阶段
开始
在C#中,项目工程(通常称为项目或解决方案)是组织代码、资源、设置和其他文件的一种方式,以便于在Visual Studio等集成开发环境(IDE)中进行开发、构建、调试和部署。以下是一个典型的C#项目工程的基本组成部分:
-
解决方案(Solution):
- 解决方案是Visual Studio中的一个容器,用于组织一个或多个相关的项目。一个解决方案可能包含多个项目,这些项目可能相互依赖或独立。
-
项目(Project):
- 项目是解决方案中的一个组件,它包含用于创建应用程序、库、服务等的代码、资源和配置。
- C#项目可以有多种类型,包括控制台应用程序、Windows窗体应用程序、ASP.NET Web应用程序、类库(DLL)、WPF应用程序、移动应用程序等。
-
文件:
- 代码文件:包含C#源代码的
.cs
文件。 - 资源文件:包含图像、图标、字符串、本地化资源等的文件。
- 配置文件:如
App.config
或Web.config
,用于存储应用程序设置和配置。 - 其他文件:如XML文件、JSON文件、数据文件等,根据项目需求可能包含不同类型的文件。
- 代码文件:包含C#源代码的
-
引用(References):
- 项目可以引用其他项目、库或程序集来获取它们的功能和类型。这些引用可以是直接的项目引用,也可以是NuGet包、COM组件或其他程序集。
-
程序集(Assembly):
- 编译项目时,代码和资源被打包到一个或多个程序集中。程序集是.NET应用程序的基本构建块,它们包含编译后的代码(MSIL)和元数据。
-
属性(Properties):
- 项目属性包含有关项目的配置信息,如编译选项、调试设置、输出路径等。这些设置可以通过Visual Studio的项目属性窗口进行配置。
-
命名空间(Namespaces):
- 命名空间是C#中用于组织代码的一种机制。它们提供了一种避免命名冲突的方式,并允许你将代码组织成逻辑上相关的组。
-
构建和部署配置:
- 项目可以配置为使用不同的构建配置(如Debug和Release)来编译代码。这些配置可以指定不同的编译器选项、输出路径和其他设置。
- 部署配置定义了如何将应用程序部署到目标环境,可能包括安装程序、Web部署或其他方法。
-
测试项目(Test Projects):
- 测试项目是专门用于编写和执行单元测试、集成测试和其他类型测试的项目。它们通常包含测试框架(如MSTest、NUnit、xUnit等)和测试代码。
在Visual Studio中创建一个新的C#项目工程时,IDE通常会提供一个模板,用于快速生成具有所需结构和配置的项目。
vs常用快捷件
Visual Studio(VS)的常用快捷键对于提高开发效率至关重要。以下是一些常见的VS快捷键,按照功能进行了分类和归纳:
1. 文件操作
- 打开文件:Ctrl + O
- 保存文件:Ctrl + S
- 全部保存:Ctrl + Shift + S
- 新建文件:Ctrl + N
- 新建项目:Ctrl + Shift + N
- 关闭当前窗口:Ctrl + W
- 关闭所有窗口:Ctrl + Shift + W
- 切换打开的文件:Ctrl + Tab 或 Ctrl + Shift + Tab
2. 编辑操作
- 剪切:Ctrl + X
- 复制:Ctrl + C
- 粘贴:Ctrl + V
- 全选:Ctrl + A
- 撤销:Ctrl + Z
- 重做:Ctrl + Y
- 查找:Ctrl + F
- 替换:Ctrl + H
- 格式化代码:Ctrl + K + D
- 自动对齐代码:Ctrl + K + F
- 上移一行:Alt + 上箭头
- 下移一行:Alt + 下箭头
3. 调试操作
- 开始调试:F5
- 停止调试:Shift + F5
- 设置或清除断点:F9
- 单步执行代码:F10
- 单步进入函数:F11
- 单步跳出函数:Shift + F11
- 运行到光标处:Ctrl + F10
4. 视图操作
- 生成解决方案:Ctrl + Shift + B
- 显示类视图窗口:Ctrl + Shift + C
- 显示属性窗口:F4
- 显示项目属性窗口:Shift + F4
- 显示资源视图:Ctrl + Shift + E
- 打开错误视图窗口:Ctrl + Alt + L
- 打开对象浏览器窗口:Ctrl + Alt + M
- 全屏显示:Shift + Alt + Enter
5. 注释和取消注释
- 注释选定的文本:Ctrl + K + C
- 取消注释选定的文本:Ctrl + K + U
6. 导航和定位
- 转到定义:F12
- 查找所有引用:Shift + F12
- 向后定位:Ctrl + -
- 向前定位:Ctrl + Shift + -
- 光标定位到窗口上方:Ctrl + Page Down
- 光标定位到窗口下方:Ctrl + Page Up
- 下一个文档窗口:Ctrl + F6 或 Ctrl + Tab
- 上一个文档窗口:Ctrl + Shift + F6 或 Ctrl + Shift + Tab
7. 大小写转换
- 选择小写转大写:Ctrl + U
- 选择大写转小写:Ctrl + Shift + U
熟悉VScode快捷键的可以在VS中窗栏"工具">"选项">"环境">"键盘">"应用以下其他键盘映射方案"中选择"Visual Studio Code",点击确定更改。
C#程序的组成结构
using System;
namespace _01第一个程序
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("aaaaaaaa");
}
}
}
- using 作用:导入内容,例如 导入系统模块
- namespace 命名空间
- class 类
- Main 程序入口 程序启动时执行Main
程序执行特点**
(1)程序员编写源代码(调用.net framework类库)
(2)源代码被编译,编译成中间代码MSIL(支持多种语言格式源代码编译成相同的中间代码)。
(3)中间代码在framework的公共语言运行时CLR环境中被二次编译成机器语言。
(4)经过第二次编译的代码在操作系统平台下运行。
.net framework:主要包括公共语言运行时CLR和类库。
数据
数据分类:
作用:将程序产生的大量数据,进行分类管理
基本类型(值类型、)
描述数字的类型有:
- 整型
byte ubyte sbyte short ushort int uint long ulong
- 浮点型
double float decimal
描述非数字的:
- 字符型char, 注意:语法单引号
- 布尔型bool
整型的区别:
- 1:占内存空间不同
- 2:描述数字的范围不同。
浮点型的区别
- float 范围太小 结尾要加
f
- decimal 占内存的空间太大,描述数字的范围特别大,128为精准十进制,28—29有效数字
- double 常规应用最多的
char应用:
- 1: 字符串遍历获取的单个字符类型为
char
,不会默认转化为字符串。 - 2:每个char 都有ASIC码的编码,所以要注意 数字char 转int是ASIC码的编码
- 3:char类型与数字之间比较,先转ASIC码再进行类型比较。
bool的应用:
- 1: 通过bool类型控制分支语句执行哪个代码块。
- 2:通过bool值,控制循环体是否执行。 true执行循环体 false 循环结束。
复杂类型(引用类型)
- 字符串
String
- 对象
- C#内置对象
object
- 自定义对象
class
- C#内置对象
- 动态类型
dynamic
- 指针类型
Pointer types
装箱/拆箱
面试容易问概念
- 装箱指的是将值类型变为对象类型
- 拆箱指的是将对象类型变为值类型。
数据类型的分类依据
依据是:数据再内存中保存方式不同。
值类型存储是具体数据,存在栈中
引用类型存在堆中
- 变量赋值值类型,保存的是具体数据
- 变量赋值引用类型,保存的是引用类型数据在堆内存中的位置,所以如果拷贝赋值引用类型的变量,一个变量改变数据,其他变量也会发生变化
拷贝
变量的赋值为另一个变量。就是拷贝
深拷贝
-
概念:变量保存值类型数据为具体数据,变量复制时,复制的是具体数据,为深拷贝
-
情况:值类型的复制为深拷贝
-
特点:多个变量赋一个值,任意一个变量值发生改变不影响其他变量
浅拷贝
- 概念:变量存储的是数据的地址,不是具体的数据。当变量复制的是地址时候,为浅拷贝
- 特点:多个变量引用同一个引用类型数据,一个变量发生改变其他变量也会发生改变
- 情况:变量赋值的是引用类型数据时,内置的:object dynamic string
- 解决方案:重新创建一个一摸一样的引用类型数据,然后变量在保存
变量
变量声明
语法结构:
数据类型 变脸名 = 值; >>> 声明变量并赋值 (挖坑,并并且往坑里添加东西)
数据类型 变量名; >>> 声明变量,没有赋值(只挖坑,坑里没东西)
int a = 123;
char c;
double d,e,f; // 创建多个变量
变量的作用
变量的作用:保存程序运行时,产生的数据
数据会在什么情况下产生
- 1:初始化赋值数据。
- 2:表达式运算的结果
变量命名规范
不要记,正常起名。英文
- 1:不能使用关键字 (namespce class Main break if for ...)
- 2:不能数字开头
- 3:不能使用特殊符号;除了 _ -
- 4: 不能使用空格
变量使用规则
必须要先声明变量,才能使用变量。
bug:使用未声明的变量报错
阅读代码变量赋值基本步骤
- 1:使用时,在使用的作用域中往上查找,看一看是否声明了该变量。
- 声明了,并且经过了多次赋值(=); 使用的是最近的一次赋值。
- 没声明。请看第二步
- 2:去上一层作用域中往上找。(指的是:只用变量的代码上面)
- 找到了,用的是上一层作用域中声明的变量,使用的是最近的一次赋值。
- 没找到:重复循环第二步的操 d作
- 3:如果到了C# 系统中
system
都没有;就会报错。
变量的作用域
变量的作用域指的是变量的使用范围
域的分解界条件:就是花括号。一个花括号为一个独立的区域
花括号情况:
- if else switch
- for forearch while do..while
- 函数
- 类
- 自己直接写一个
{}
作用域关系
- 1:花括号嵌套花括号,我们叫做父子关系
- 2:同一个花括号下两个或者多个同级花括号,我们叫做 相抵关系。
作用:
- 子作用域可以访问父作用域及祖籍作用域中的变量
- 相邻的兄弟之间作用域不可以相互访问\
- 特殊:
- 函数中声明的变量只能函数内部访问,函数外部无法发访问
- class类中声明的变量 只有带有
static
修饰符的 在类的内部可以直接使用 - for中
()
定义的变量只能在 循环体{}
中使用 - foreach的() 中创建的变量,只能在循环体中使用
- if 的
{}
中创建变量只能在if中使用。 if的()
不能创建变量
训练方式: 通过现有的代码,画方块方式,画出,作用域关系。>>> 知道变量的使用。
变量的声明规则
- 1:在同一个代码块中不能重复声明
- 2:父作用域中已经声明过的变量子作用域中不能重复声明
- 3:
namescape
不能声明变量 - 4:
class 函数 if for {} ..
中都可以声明变量 - 5:一个变量只能赋值一种类型数据,不能赋值其他类型。
数据类型转化
系统数据之间存在兼容性:
- 显示转化
- 隐士转化 (自动转化)
系统数据类型之间不兼容:
Convert
类进行类型转化。Convert.ToInt32() Convert.ToDouble() Convert.ToChar Convert.ToString
- 其他类型转int
- int.Parse()
- 其他类型转string
- xx.ToString()
数据类型转换的不兼容性:
- 数字和布尔不能类型转换
- 字符和布尔不能类型转换
- 字符转数字可以自动转换,数字转字符只能强制转换
- 字符和数字相互转换的时候使用ASCII编码来进行转换
如果转化中可能存在错误问题;为了程序可以正常运行;使用
try..catch
运算符
作用
用户进行数据之间运算的。
常用分类
-
算数运算符
+ - * / & ++ --
- ++ 自增,运算规律加加在前,先自增 后赋值,佳佳在后 先赋值,在自增注意:这是两步运算,一个是自增一个是赋值
- -- 自减 ,每次运算自身减少1, 运算规律减减在前,先自减 后赋值,减减在后 先赋值,在自减
-
比较关系
> < >= <= == !=
-
逻辑
! && ||
!bool
表示取反,bool为true ,取反后结果为false&&
左右两边的结果都是 true ,&& 运算结果才是true,否者为 false||
只要由一个true ,||
运算结果为true, 否则 false
-
赋值
= += -= /= %=
-
其他运算符
typeOf()
返回 class 的类型;作用:验证某个数据是否为某个类型sizeOf()
返回数据类型的占据空间大小?:
三元运算符号is
判断对象是否为某一类型as
强制转换,即使转换失败也不会抛出异常。
注意事项
- 1:注意:只有相同类型的数据之间才能进行精准计算运算 【错误的,为了写代码可以养成习惯】
- 2:int 与 double 计算 省略小数点
- 3:char 与int double 运算 先ASIC码的编码 在计算
规律
- 1:只要表达式中存在 比较关系运算符或者 逻辑运算符;返回值一定是
bool
类型 - 2:
+
只要存在一个字符串,作用:拼接字符串。注意:必须是左右两边操作数其中一个必须是字符串的情况
"aaa" + 123;
注意:第一个加号是算数运算符,第二个加号才是链接运算符
1+2+"aa"
- 3:相同类型之间算数运算,结果一定是相同类型。例如:
double double 结果是 double
- 4: 注意赋值运算符。可以实现给一个变量多次赋值。注意:累计的结果(累加 )
- 5:赋值运算符最后一个运算(应用层面)。
表达式
组成
最少需要两个操作数和一个运算符 才能组成一个表达式;
特殊:++ -- ! 与 一个操作数就可以生成表达式
特点
表达式一定会由运算结果,也就是新的数据。
开发者编写代码,就是在写各种各样表达式,根据已知条件,编写表达式。
- 条件表达式
- 算数运算表达是 (小学数学
一维数组
特点:
- 1:有索引值,长度固定。数组元素类型一样
用途:
- 如果需要将多个相同类型的数据,存放在一起时,用数组保存。例如
- 游戏地图坐标位置。
- 游戏人物角色
数据处理
- 遍历:通过for获取数组中每个元素
常用api:
-
arr.length
获取数组长度 -
Array.Clear()
清空数组,数组中元素恢复到默认值- int[] 默认值为0
- double[] 默认值为0
- char[]默认值
''
- string[] 默认值为 空字符
-
Array.Copy(Array1, Array2, len)
将Array2中元素从第一个元素开始,获取len个元素,赋值到 Array1中 -
Array.GetLength()
获取指定维度数组的长度,返回值为int类型 -
Array.Reverse(array)
颠倒数组元素位置。返回逆转后的数组 -
Array.Sort
(array) 将参数array数组进行升序排序。返回排序后的数组 -
ArrayindexOf(array,item).
查询item是否在array数组中存在,不存在返回-1 存在返回第一次出现的位置
分支语句
一般用于一个业务中,存在多种情况,不同情况执行不行代码
单分支
if(bool条件表达式){
// true 执行 false 跳过
}
双分支
if(bool条件表达式){
// true 执行 false 不执行
}else {
// false 执行
}
多分支
if(bool){
// true 执行,其他分支不执行 false 继续往下验证
}else if(bool){
// true 执行,其他分支不执行,false 继续往下看
} else {
// 所有的条件表达式返回值都是false执行
}
switch(变量){
case 值1:
// 执行语句
break;
default:
// 执行语句.所有case 都不执行 执行这里
break
}
循环语句
特点:将一个有规律,重复执行的代码片段,放在一个代码块中,就是循环
分类
- for
- while
- do..while
- foreach
for
一般用于 已知村换次数,的业务中
for(int 变量 = 初始值; 条件表达式;自增/自减){
// 循环体,这里编写重复有规律的代码片段
}
执行过程:
1:先执行初始化表达式;
2:再执行 条件表达式,运算结果为 true,再执行循环体
3:执行自增,条件表达式true ,循环体;false for循环执行结束
注意:
- 1:初始值表达式 声明的变量只能for的内部使用,外部不可以访问
- 2:for结束后,不会再次重新执行for
- 3: for执行一;循环体执行多次。条件表达式为循环体是否执行的开关
while
一般用于:不知道循环次数,但是知道结束条件的业务中
while(bool条件表达式){
// 循环体:这里编写有规律的重复执行的代码片段
// 条件表达式,为true 循环体执行 false while结束
}
注意:
- 1:结束while的方式有:
- 1:条件表达式为false
- 2: break
- 3: 在函数中使用while ,return
do...while 与while 一样
foreach
作用:用于遍历数据;要求数据类型必须一样
forearch(type 变量名 in 数组){
// 变量名赋值:数组元素 单个字符...
}
循环嵌套
- 1:外循环执行一次,内循环执行多次
- 2:内循环不执行完毕,外循环也没结束;
静态循环嵌套
for(int i = 0;i<9;i++){
for(Int j = 0;j<9;j++)}{
// 内循环 每次执行for 初始值和条件表达式都是固定不变的;
// 结果:外循环执行一次;内循环执行的次数固定的
}
}
动态嵌套1
for(int i = 0;i<9;i++){
for(Int j = i;i<9;j++)}{
// 初始表达式每次赋值不一样,实现动态内循环次数
// 内循环执行次数是动态变化的。
// 外循环每次执行时候 内循环的循环体执行次数都不一致
}
}
动态嵌套2
for(int i = 0;i<9;i++){
for(Int j = 0;j<i;j++)}{
// 条件表达式,每次外循环执行时,内循环都不一样。实现内循环动态变化
// 内循环执行次数是动态变化的。
// 外循环每次执行时候 内循环的循环体执行次数都不一致
}
}
如何区分业务需要嵌套循环
- 1:画图:表格形状。外循环为函数;内循环为列数
- 2:排序,去重。
- ........
- 注意:
循环是同步代码,按照开发者编写的代码顺序从上往下执行。不会跳跃性的执行,只有等上一句执行完毕后,才能继续执行下一步。
函数
基本结构
定义函数基本结构:
修饰符 返回值类型 函数名(参数1,参数2...){
// 方法体
}
函数执行基本:
函数名(实参,实参)
参数
分类
- 形参
- 作用:定义函数局部变量,等待函数执行时赋值
- 实参
- 作用:具体数据,给形参赋值,赋值位置与形参一一对应;
值参数
- 1:定义多个形参。每个形参类型不确定,函数执行时可以执行赋值
static void Foo(string str,int a){
}
Foo("123",123);
ref引用参数
static void Foo(ref int a){
a = 345; //
}
int c = 123;
Foo(ref c); // C 为 345
用途:输出函数运算结果,赋值给被引用的变量
- 1:实参传递的不是具体的数据;是变量的引用
- 2:变量引用:多个变量只要有一个发生改变其他的也会发生改变。
out输出参数
static void Foo(out int a ){
a = 123;
}
int c;
Foo(out c); // C 变为123
用途:用于输出函数的运算结果;赋值给函数外部的变量
params不固定参数
static void Foo(params int[] arr){
foreach(int item in arr){
// item 为实参 1,2,3,4,5
}
}
Foo(1,2,3,4,5)
当函数的实参数目不固定,多个。可以用params参数
- params 参数是一个参数数组。通过遍历方式获取每个实参
返回值return
作用:
- 输出函数表达式运算结果。注意:需要重新创建一个变量接收。
- 与ref out不同,ref与out 函数外部已经存在变量了
- 结束函数语句
static int Foo(int a ,int b){
return a+b;
int c = 1;// 不执行的
}
int c = Foo(1,2); // c 为 3
注意事项
- 1:函数中声明的变量,局部变量只能在函数内部使用
- 2:函数执行时,会声明变量,赋值... 函数执行结束,变量销毁。
- 3:函数每次执行都是初始化。
- 4:只能在class类中定义函数。
函数执行时候;函数创建的变量会在堆内存中开辟空间,当函数执行结束;释放堆内存的空间;
函数调用权限
- public 只有public 函数调用:1:创建类的实例对象; 2:
实例对象.函数名()
调用函数 - static 只要有static 函数只能在本类中直接使用,其他类不能使用
- public static 指的是在任意的位置 都可以i通过
类名.函数名()
调用函数,本类 其他类都可以使用
函数封装思路
- 1:确定函数的功能、
- 2:根据功能确定函数名字
- 3:确认函数形参,以及每个形参的作用。(原材料)
- 4:确认函数执行完毕后;输出内容类型是什么?作用是什么
- 5:分析:从形参变成返回值完成函数功能的具体实现步骤是什么
枚举
-
用途:如果一组数字,表示不同业务;可以使用枚举描述
- 星期
- 网络状态码
- 订单状态
- 各种状态码描述xxx
-
注意:枚举是一个数据类型 叫做枚举型。枚举中的多个数据都是枚举型--
-
定义枚举:
enum
-
枚举名:
- 1:开头字母大写,大驼峰
-
枚举项:
- 1:可以是字母 汉字..
- 2: 类型为枚举类型
- 3:每个枚举项都会对应一个int值,默认从0开始依次增加1
- 4:枚举项可以修改默认值,下一项,在上一项基础上加1
-
枚举基本使用
修饰符 enum 枚举名{
枚举项1,
枚举项2,
}
public enum Day {
Sun, Mon, Tue, Wed, Thu, Fri, Sat
}
// 获取枚举类型;
Day.Mon // Mon 注意:不是字符串,是枚举类型
// 获取枚举的值:*****
int a = (int)Day.Mon //`a 为 1;
结构体
将多个不同类型的数据,放在一起的时,可以使用结构体
// 结构体可以放一堆变量 或者函数
修饰符 struct 结构体名 {
变量1;
变更2;
函数1;
}
// 定义一个抽象结构体。
public struct Books
{
public string title;
public string author;
public string subject;
public int book_id;
};
// 创建具体的结构体数据,
Books aa = new Books;
aa.title = "C#开发";
aa.author = "视觉17";
aa.subject = "aaaa";
aa.book_id = 123213;
-
结构体也是自定义的静态类型。
-
结构体抽象。抽象是用于创建具体数据。
-
结构体中的变量;可以赋值任意类型数据。