【namespace】
命名空间下,只能写类和委托;
作用:用于归纳整理。比如:鸟类,植物类,电器类等,同一个项目使用同一个命名空间。
。net有众多类,全放一起,无法快速检索到需要的类。
所以用【点】来区分,注意【点】不是包含关系。
解决类重名问题时,要用完全限定名来区分。【完整命名空间路径】
命名空间下:【class类】,【delegate委托】
VS软件,类库:右键类库属性,修改【默认命名空间】
配合引用:using
//【1】声明委托(方法的原型)
public delegate void LectureDelegate1(); //命名空间下,可以定义委托类型【全局变量】
【class】
静态类:类的成员使用非常频繁的时候用static
人类 秘书 = new 人类(18);
bool 工作结果 = 秘书.方法A(x);
作用:new出实例对象,然后让对象干活{调用方法}。
class类是namespace下最小元素。跟公司的员工一样,是最小的。比如 金木水火土 是最小的元素。
一个标准的class类,包含{字段,属性,构造方法,自定义方法}
每次编辑class就相当于修改汽车图纸,成熟的项目里,只需要new出class对象,相当于按图纸生产出汽车。
class的自定义构造方法是带参数的,参数相当于你的定制款,比如汽车颜色你选灰色。
这样new出对象时 汽车图纸 苏DD16842 = new 汽车图纸( Pro,哇塞灰 );
类内不能直接写方法调用。必须在方法体内写,方法调用。
父类定义的方法,能否被子类的同名方法【顶替】?答:可以,需要加new关键字。
集合内,new对象时用 对象初始化器。见构造方法。
GC.Collect(); //这个其实是由虚拟机帮我们完成,我们没必要多管闲事!
第二种class用法:
这种class主要运用在,方法的参数是对象。
方法的参数过多会导致,错写,漏写等情况。
所以,这种class对象,她只有属性。new出对象后,当做参数对象,传给方法。
这种class类型,一般放在【Models】文件夹内,她是全局变量类型。
第三种类用法:
【封装】:把对象拆解成{字段,属性,方法}的class类。方法包括构造方法,自定义方法,扩展方法等。
【继承】:一般做功能扩展用,每个儿子都需要用到父亲的一些方法和属性,用继承可以节省写重复的代码。子类只需要填写要增加的方法。
【多态】:儿子使用父亲的东西,和父亲使用儿子的东西。
要注意同名方法实际为独立的2个方法。只有override才会顶替。父类的用base。
并且,子类和父类同名方法冲突,用new关键字隐藏后,仍然是独立的2个方法。
如果儿子含有跟父亲同名的{属性,方法}时,需要加new关键字解决,
父亲的同名属性和方法将被隐藏。2个同名的属性或方法是完全独立的。
父类的属性或方法需要用【base.】才能调出。
子类同名方法,强制转换给父类,不能污染父类同名方法,需要用接口或 override才能实现。
abstract:抽象只声明方法,没有方法体。
virtual:虚方法,做默认方法用,跟默认参数一样的。
public override void //重写同名方法【顶替】。不用override为独立的2个同名方法。
父亲要求儿子必须裂变,用【抽象方法/接口方法】:每个儿子同名方法体都不一样,用父亲的抽象方法管理这群儿子。
接口Type CAN总线通讯 = (接口Type)儿子_有人CANET200;
父亲不要求儿子都裂变,用【虚方法】:儿子可以不重写父亲方法,就继续使用父亲的默认方法。
【接口】:interface,父类要求儿子必须裂变。每个儿子方法体都不一样。当2个接口出现同名方法时,要用接口类型显示定义。
【反射】:Assembly实际上利用接口,主程序规定接口类型,反射是在程序集dll/exe文件内,导出子对象,赋值给父类接口,实现多态。dll文件可替换,所以子类实例也可替换。
【字段】
字段,属性,他们在类内部都是全局变量。
作用:在class类内,做全局变量使用。
类内部的全局变量。外界不能直接访问读写。
字段加public后,这种设计不合理,而且控件也不能正确显示。
【static】作用是所有派生的子对象,都使用同一个变量值。
int StudentAge => DateTime.Now.Year - DateOfBirth.Year;
【属性】
属性也能实现方法功能,设计时,要看职责 。
事件{1章14节} 有静态属性?
作用:只作为【字段】的输入输出连接用。
只作为与外界数据交换。间接地访问到字段。
public int StudentId { get; set; }
public int StudentAge => DateTime.Now.Year - DateOfBirth.Year;
通常对接收的数据做范围限制。只读,只写,只能某一段范围值。
public string CourseName { get; } = ".NET全栈开发课程";
也可以做日志刷新等动作。// 属性的本质就是方法
prop 单行属性
【构造方法】
初始化内容在构造方法中写。
对象本体用 this.
C#会提供一个默认构造方法。
在new的时候,会执行一次对应的构造方法。【相当于种豆得豆】
可以编辑默认构造方法,修改属性后,以后new出的实例对象都会跟着改变。
构造方法,相当于实例对象刚出生时需要做些部署,每次new都会执行一次构造方法。
需要注意static,它只执行一次。
当自己写了【有参构造方法】,那默认构造方法就会消失,需要手动添加。
【有参构造方法】相当于定制汽车的配置。内饰颜色,轮毂大小等。
【构造复用】
构造方法名字(参数1,参数2,参数3)
:this(参数1,参数2) //继承父类用 :base(参数1,参数2)
{
this.参数3=参数3;
}
【析构函数】
~类型名()
{
日志;
}
【对象初始化器】//也叫属性初始化器,只能初始化属性,构造方法可以初始化字段,
和方法部署。
学生 小明 = new 学生()
{
属性1=xxx,//【属性之间用逗号隔开】
属性2=xxx,//【属性之间用逗号隔开】
属性3=xxx //【最后一个属性,不加符号】
};//【分号】
Student student = new Student()
{
DateOfBirth = Convert.ToDateTime("1996-09-10"),
StudentId = 1003,
StudentName = "全栈VIP课程学员小李"
};【强制参数赋值】//《命名参数》可以打乱参数赋值顺序。
方法A(stuid:2024,stuName:"学员李四" );
【方法】
指定参数赋值
result = student.GetStringStudent(studentId: 20002, studentName: "上位机学员李四");
子和父,同名方法,能否被顶替?【不能,是2个独立的同名方法,要用override】
在C#里称:方法
在C语言里称:函数方法 实际它们是同一个东西,只是称呼不同。都是描述行为。
方法默认参数:方法默认参数必须放在最后,public string 方法A(int a,int b,int c=55)
静态方法: 加static,不受实例约束,用类型去调用。{1章12节}
调用实例对象属性用【this.】
静态方法不能调用实例方法。静态方法用于高频调用。
方法自动对齐: Ctrl+K+D
Pascal命名:首字母大写【类,属性,方法】
Camel命名:首字母小写【变量】驼峰
下划线命名:匈牙利命名法,age 跟 _age是两个变量。
注释: //单行注释 /* 局部注释 */ ///文档注释
帮助:点击标识符,按【F1】,会跳转到在线帮助文档。
折叠代码: #region
oop:将{数据}和{行为}封装成class,new出 对象
在C#里【指针函数】的替代品是【委托】
【委托】:原因:主窗体内可以调用子窗体的方法,子窗体不能直接调用主窗体的方法。
1:在他们2个类的公共区定义(命名空间下),【委托类型】一般在子窗体内定义,因为主窗体可以直接访问子窗体内属性成员。
2:主窗体绑定委托【将主窗体的方法绑定到属性委托】相当于制作快捷键。利用属性。
3:子窗体调用属性委托【相当于调用快捷键,快捷键会执行指向主窗体的方法】。利用属性,在子窗体方法内,调用委托属性。
委托绑定用【+=】【-=】和【=null;】
可以先 =null;然后再 +=绑定方法
方法2
由于变量的类型是方法,系统已在公共区域{命名空间下}定义了2个委托类型。
用户可以使用匿名方法 (a,b)=>{a+b} <T1,T2,T3>(T2 a,T1 b)=>{return T3 c=a+b;}
【方法类型委托】 变量n = <标记类型1,类型2,返回类型3>(T1 a,T2 b,T3 c)=>a+b;
Func:有返回值 <参数1,参数2,返回值>
Action:无返回值
【架构】
小型项目用3层架构: 老板》领导》员工
原材料是【老板,领导,员工】的公共区域。
宏观上看:输入跟输出,不用关心内部到底是怎样处理数据的。
老板: new出原材料,传给领导。//调用领导方法
领导:调用不同员工输入输出原材料。对老板输入输出原材料。{业务办理}
员工:只做分布式io作用,不具备程序处理。{寄存器参数输入输出}
整个过程中:原材料【参数】都可能被他们new,赋值,丢弃。
数据隔离:老板不能直接调用员工方法。老板只调用领导方法。
【老板】:相当于主程序
【领导】:相当于功能块,带业务逻辑,实现功能。
【员工】:相当于分布式io,只做数据输入输出用。
【实例类型】:全局参数,参数的类型是对象。
【中大型框架】
1章19节:
同一个项目下,添加【类库】 ,类库下添加,类
【 UI】老板,//只调用BLL,不调用DAL,与DAL数据隔离。
【BLL】领导,//带业务逻辑功能
【DAL】员工,内包含{Help_二次开发库},//只输入输出数据{一般数据访问,通用数据访问}
【Models】全局的,实例化参数对象new时要用的类型。//方法的参数是对象
在添加类库后,ui只引用【BLL和models】,BLL只引用【DAL和models】,DAL只引用【models】。
models的作用就是参数类型,必须是全局作用域,因为参数过多会错写和漏写,所以用对象来传递参数,这种class对象,她只有属性,阉割掉了字段和方法部分。
【可序列化标记】
【Serializable】 // serial i zable 可串行化的 [Serializable]
BinaryFormatter formatter = new BinaryFormatter();
FileStream fs = new FileStream("C:\\objStu.obj", FileMode.Open);
【序列化】
formatter.Serialize(fs, objStu);
【反序列化】
Student objStu = (Student)formatter.Deserialize(fs);
【事件】
属性 / 方法的参数变量类型是 【方法类型】
在他们2个对象的公共区域定义委托类型【在命名空间下定义委托类型】
class对象的一个属性值,她的类型是方法。
public event EventHandler Load
这个 event 是关键字
这个 EventHandler 是委托类型【C语言里的:函数指针】是在全局作用域处定义。{命名空间下}。
跟她绑定的方法签名,也必须一致。
实例子对象,调用该属性时,就会触发与之绑定的方法。
namespace System
{
[Serializable]
[ComVisible(true)]
[__DynamicallyInvokable]
public delegate void EventHandler(object sender, EventArgs e);
}
public FrmMain()
{
InitializeComponent();
this.Load += FrmMain_Load;
}private void FrmMain_Load(object sender, EventArgs e)
{
this.txt_IP.Text = IniConfigHelper.ReadIniData("PLC参数", "IP", "", ConfigPath);
this.txt_Port.Text = IniConfigHelper.ReadIniData("PLC参数", "Port", "", ConfigPath);
}
【故障处理】
try
{//只放可能错误的代码}
catch (Exception)
{//错误处理throw;
}
finally
{//始终执行}
【dll文件】
dll文件,实际是【类库】文件,models,DAL,BLL这样的库。他们的文件就是dll文件。
我们除了用自己写的库,还可以用别人写的库。【项目】》【引用】》【管理NuGet】,
添加如:xktcomm,NModbus4,PCHMI,西门子S7协议【S7netplus】等。
自己项目的。net版本号,不能小于第三方的版本。
查看【方法体】需要安装插件:【扩展】》【管理扩展】》【iLspy2022】
。重启一下vs软件。
【值】
用bit长度来存储数据,并且可能带符号。
同样的8bit数据,如果带符号,最高位是【正负符号bit】后7bit才是数值。
1bit bool false/true
u8 byte 0~255
u16 ushort 0~65535 unsigned short
u32 uint 0~42 9496 7295
u64 ulong 0~1844 6744 0737 0955 1615
i8 sbyte -128~127
i16 short -32768~32767
i32 int -2147483648~2147483647
i64 long -9223372036854775808~9223372036854775807
i128
转换 类型.Parse // int.Parse
float 32bit小数 // 3.1415926f // -7.654f
double 64bit小数 // 3.14159d //可以不加d -98.7654
decimal 128bit小数 -98.76m 3.14mobject 容器
string 字符串
char 单字符
DateTime 日期
【注】int的bit长度受CPU位数限制。Int64 e= unchecked((Int64)(0x8000000000000000));
int Bytelen = sizeof(decimal); // 16 byte【总长16字节】
【引用类型】:类,数组, //整体赋值后会导致修改B后,A的值也会改变。
【值类型】:结构体,byte等
enum 枚举
union 共用
d
【string】
万物皆文本
+
-
=
格式输出 string.Format( " " ); // @原样输出 $用占位符
string.Format( @" 地址原样输出 C盘/temp " );
string.Format( $" {变量第一个} " );
string.Format( @$" " );
【StringBuilder】
【赋值】
方向:从右到左
好的写法能方便数据分析和设备调试。
int num = 0b00001111; //二进制写法 0b开头
num = 0b111 << 5; // 1110 0000
num = 1 << 7; // 1000 0000
// 常规用法
decimal pai = 3.14159f;
pai = 12345m;
pai = 255;
pai = 0xff; // 十六进制
pai = 0B00001111; //0x0f
textBox3.Text += "你好!" + '\u000d' + '\u000a'; // 0x0000 到 0xFFFF;
string txbuffer2 = "要发送的数据。";
tx=Encoding.ASCII.GetBytes(txbuffer2);
rx=Encoding.ASCII.GetString(tx);// 解码
Encoding.UTF8.GetBytes
Encoding.UTF8.GetString
Encoding.BigEndianUnicode.GetBytes
Encoding.BigEndianUnicode.GetString
Encoding.UTF7.GetBytes
Encoding.UTF7.GetString= 赋值【从右向左】
+
-
+=
-=
* 乘
/ 除
% 取余
++ 自增
-- 自减
【其他类型】
object 盒子类型 //数据是二进制保存的,相当于截取二进制长度
dynamic 动态类型,运行的时候确定; dynamic d = 20;
char* 指针类型 char* cptr; int* iptr;
bool 1bit false,true//假,真 逻辑关系
char 16bit 相当于照片的编号,输入索引值,显示出对应文字/符号的照片 '\u0000'到'\uFFFF'
string 字符串类型,是连续的char的倍数长度,一般用于输出连续文字和符号
char[] 转string需要用 new string(char数组);
StringBuilder 可变字符串:StringBuilder 坤=new StringBuilder("坤",49);// 最大49字
DateTime 时间类型 string ATtime = DateTime.Now.ToString("ss's'ffff:");// xx秒xxxx毫秒
class 对象类型(参数引用类型传递)
struct 对象结构体类型(参数值类型传递)
enum 枚举类型(有明确范围个数的,比如星期)
union 共用体(最大类型容器)
byte[,] 数组类型(引用类型)new byte[8, 13];
sizeof() 获取数据类型的字节大小 byte num = sizeof(int);
typeof() 返回class类型
nameof() 输出变量的名字。
& 取变量的地址 函数方法前需要 unsafe修饰,然后工程要开启不安全代码。
* 指针,指向地址,返回对象
?: 条件表达式
is 判断是否为某一类型
as 强制转换【不会抛出异常】 Object obj = new string("维修电工!");
string str = obj as string;
C# 摒弃了指针写法,用ref和out代替指针,函数指针用委托代替。
————————————————版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/cfqq1989/article/details/127291730
【上位机与下位机】
这个只需要简单了解下。
上位机与下位机:就好比遥控器飞机和遥控器的关系。
遥控器发命令控制飞机,飞机反馈摄像头的图像给遥控器。
。net里是UI控制到class实例对象,实例对象调用方法,方法再控制到电脑的通讯口。
上位机也可以理解为就是控制通讯。
有:数据库,Modbus RTU,Modbus TCP,CAN等。
机器设备之间:数据帧可以理解为string,万物皆文本,string转到方法,需要使用到对象字典。
对象字典(key键,Value值); public Hashtable()
可以理解成【快捷键】和【函数方法】,比如:你按下汽车按钮,实现对应的功能。
程序员更多的是对数据库操作:增删改查。 这个只能保存class对象的属性,无法保存对象的 方法,一般new出对象后,是自带方法的,只是属性不一样。
就好比new出一辆车,进退左右这些功能方法都有,唯一区别就是属性,车牌,颜色等不一样。
【数组】
static byte[,] buffer = new byte[8, 13];
【体】【层】【横】【纵】
←
【集合】List
List<T>
List < Course> 管家 = new List <Course>(){course1,course2,course3};
public class List < T > : IList<T> {.....}
public T this [ int Index ] { get; set; }
【数组转集合】.ToList();
【集合转数组】.ToArray();
【集合加数组】.AddRange();
random.Next(33);//返回随机小于33的值。
T.Count //对象总数量
T.Contains //是否包含
T.Add //添加对象
T.
static T Add1<T>(T a, T b) where T : struct
{
// return a + b; //直接使用是错误的dynamic a1 = a; //解决方法:default关键字
dynamic b1 = b;
return a1 + b1;
}
泛型:第3方管家,来管理同类型的集合。【1章13节】
本质是数组去掉下标限制,再做对象的集合。
集合显示 DataGridView
this.dataGridView1.DataSource = 字段集合对象;
ArrayList 对【类型】集合的处理,遍历.Count,添加Add,删除Remove,插入Insert
Hashtable 【字典】添加Add,删除Remove,键Key,值Value,
用于上位机与下位机string文本,调用方法。
查找包含Contains,
查找键ContainsKey
查找值ContainsValue
this 子对象
public void setName(String name)
{
this.name = name;
}
<T> 泛型,占位符,相当于管家// 在集合内找出实例对象
定义
public GetType<T> (T t)
{
Console.WriteLine(t.GetType());
}
上层
p.GetType<int>(123);
List < Course> 管家 = new List <Course>();
管家.Add(course2);
管家.Sort()升序 .Reverse()倒序
管家.Sort()升序 //指定用某一属性排序 class Course:IComparable<Course>
List < Course> 管家 = new List <Course>(){course1,course2,course3};
【集合查找1】List<T> a1 = xxlist.FindAll(c=>c.Courseid>10003);
【集合查找2】 var a2= from c in xxlist where c.Courseid > 10003 select c;//异步查询
【集合查找3】foreach( Course item in courseList)
【集合查找4】for( int i=0 ; i< courseList.Count ; i++)
【裁剪】Button btn = sender as Button;
【字典】(键,值) Dictionary
Dictionary<string,Student> stuDic = new Dictionary<string,Student>()
{
["软件A班"] = class1List,
["软件B班"] = class2List,
["软件C班"] = class3List //最后一个没符号
};
foreach(string key in stuDic1.Keys) // .Values
调出对象 stuDic1["软件A班"].
判断是否有这个key? bool start = stuDic1.ContainsKey("软件A班");
【窗体中集合】父类对象 Controls ,每个Form控件对象会继承 Controls
foreach( Control item in this.Controls)
if( item is Button)
Button btn = item as Button
if ( btn.Tag != " Save" )
btn.Click += new System.EventHandler(this.btn_Click);
【文本】
char
;单引号表示字符【‘A’】
转义【‘\‘’】\r回车 \n换行 \t制表符 \f换页 \"双引号 \\反斜杠
\b退格 \'单引号 '\uFF15' 十六进制的单字符
string
;【“用双引号表示”】
判断相同 Compare -1 0 1
bool相等 Equals
格式化显示 Format c货币,d负十进制,e指数,f小数,n小数,p百分比,x十六进制
DateTime.Now.Millisecond F
截取 Substring
分块 Split
插入 Insert
删除 Remove
复制 Copy
替换 Replace(旧,新)
StringBuilder 减少内存开销
追加 Append
格式追加 AppendFormat
插入 Insert
删除 Remove
替换 Replace
【封装继承多态】
封装:对象解释为【属性】【方法】,在C#里指【类class】
继承:重复性的代码用继承。先写个发动机,再继承给轿车,SUV等
多态:父类只有方法名,没有方法体。子类有方法体。将不同的子类裁剪给父亲,
这样,父亲使用同一个方法名,能实现子类的特征。【常用 抽象,接口,虚方法】
public virtual void 方法A()
public override void 方法A()
abstract interface
【GDI】
画画
Graphics 画画师;
Pen 画笔 = new Pen(Color.Black,3);
Point point1 = new Point(10,50);
Point point2 = new Point(100,50);
;
画画师.DeawLine(画笔 , point1 , point2 ); // 直线
矩形 DraRectangle
椭圆 DrawEllipse
圆弧 DrawArc
扇形 DrawPie
多边形 DrawPolygon
【文本】 DrawString 文本,字体,颜色,位置
【图像】 DrawImage
柱形 FillRectangle
【折线】 FillEllipse
饼形 FillPie
【路径】
绝对路径
;
;
相对路径
;
;
【特性】
STA Thread
[STAThread]
[Serializable] // 序列化
【线程】
Thread
启动 Start();
暂停 Suspend();
继续 Resume();
休眠 Sleep(毫秒);
结束 Abort();
【】
c
【规避】
1 懒
2 好色
3 爱拖延
4 精神内耗
5 不思进取
6 自控力差
7 想的多做的少
8 做事三分热度
9 眼高手低
10 没主见
【Time】定时器
控件可见,组件不可见。
Time有3种:
窗体定时器:工具箱》Time》// this.time1.Start()启动 .Stop()停止
线程定时器: