机器视觉应用C#开发基础第一阶段

51 阅读20分钟

C#基础第一阶段

开始

在C#中,项目工程(通常称为项目或解决方案)是组织代码、资源、设置和其他文件的一种方式,以便于在Visual Studio等集成开发环境(IDE)中进行开发、构建、调试和部署。以下是一个典型的C#项目工程的基本组成部分:

  1. 解决方案(Solution)

    • 解决方案是Visual Studio中的一个容器,用于组织一个或多个相关的项目。一个解决方案可能包含多个项目,这些项目可能相互依赖或独立。
  2. 项目(Project)

    • 项目是解决方案中的一个组件,它包含用于创建应用程序、库、服务等的代码、资源和配置。
    • C#项目可以有多种类型,包括控制台应用程序、Windows窗体应用程序、ASP.NET Web应用程序、类库(DLL)、WPF应用程序、移动应用程序等。
  3. 文件

    • 代码文件:包含C#源代码的.cs文件。
    • 资源文件:包含图像、图标、字符串、本地化资源等的文件。
    • 配置文件:如App.configWeb.config,用于存储应用程序设置和配置。
    • 其他文件:如XML文件、JSON文件、数据文件等,根据项目需求可能包含不同类型的文件。
  4. 引用(References)

    • 项目可以引用其他项目、库或程序集来获取它们的功能和类型。这些引用可以是直接的项目引用,也可以是NuGet包、COM组件或其他程序集。
  5. 程序集(Assembly)

    • 编译项目时,代码和资源被打包到一个或多个程序集中。程序集是.NET应用程序的基本构建块,它们包含编译后的代码(MSIL)和元数据。
  6. 属性(Properties)

    • 项目属性包含有关项目的配置信息,如编译选项、调试设置、输出路径等。这些设置可以通过Visual Studio的项目属性窗口进行配置。
  7. 命名空间(Namespaces)

    • 命名空间是C#中用于组织代码的一种机制。它们提供了一种避免命名冲突的方式,并允许你将代码组织成逻辑上相关的组。
  8. 构建和部署配置

    • 项目可以配置为使用不同的构建配置(如Debug和Release)来编译代码。这些配置可以指定不同的编译器选项、输出路径和其他设置。
    • 部署配置定义了如何将应用程序部署到目标环境,可能包括安装程序、Web部署或其他方法。
  9. 测试项目(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
  • 动态类型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(变量){
  case1// 执行语句
     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;
  • 结构体也是自定义的静态类型。

  • 结构体抽象。抽象是用于创建具体数据。

  • 结构体中的变量;可以赋值任意类型数据。