深入.NET平台和C#编程

本文深入探讨了.NET框架的基本构成,包括CLR和FCL的作用,详细讲解了C#中的数据类型、集合操作、类的方法、继承与多态等核心概念。通过实例解析,帮助读者掌握面向对象编程的关键技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

深入.NET平台和C#编程

一. netFrameWork框架

运行在操作系统上,是.net的基础环境它由两部分组成,分别是CLR,FCL

1、CLR:公共语言运行时

​ 运行环境
​ 基本规范:

	.1、CTS:规范类型(type)
	   C#:int--->int32
       java:int/Integer-->int32
	   Convert.ToInt32()
   .2、CLS:规范语法(language)

	.3、MSIL:中间语言
       java/C#数组:

2、FCL:框架类库

表示一部分已经被封装好的功能的集合
用法:引用命名空间

3、面向对象的回顾

定义: 类是对象的抽象,对象是类的具体

类的三大特性:

(1)类的特性:封装:将一些特性私有化,将底层(实现过程)藏起来(实现方案:将内容用方法包装)

  private int age;
		public int Age
		{
			get{}
			set
			{
				if(age > 10){有错}
			}
		}

(2) 继承:子承父业
(3)多态:一个事物的多种形态

定义类:

public class 类名
	{
		字段私有
		属性:get[只读]、set[只写]
		方法
	}
public class 示例
    {
        private string _name;
        public string Name
        {
            get { return Name; }
            set { _name = value; }
        }
    }
  class Student
    {
        public int ID;
        public string name;
        public int age;
        public string address;
    }
    static void Main(string[] args)
        {
            Student stu = new Student();
            Console.Write("请输入编号:");
            stu.ID = Convert.ToInt32(Console.ReadLine());
            Console.Write("请输入姓名:");
            stu.name= Console.ReadLine();
            Console.Write("请输入年龄:");
            stu.age = Convert.ToInt32(Console.ReadLine());
            while (stu.age <= 18)
            {
                Console.WriteLine("学员年龄必须大于等于18岁");
                Console.Write("请重新输入年龄:");
                stu.age = Convert.ToInt32(Console.ReadLine());
            }
            Console.Write("我的家庭住址为:");
            stu.address = Console.ReadLine();
            string XxI = string.Format("我的编号为{0},姓名为{1},年龄为{2},家庭住址为{3}",   
            stu.D,stu.name,stu.age,stu.address);
            Console.WriteLine(XxI);
            Console.ReadLine();
        }

类成员:字段,属性,方法
类怎么使用:

通 过 对 象 类 名 对 象 名 = n e w 类 名 ( ) ; 对 象 : 对 象 名 . 属 性 [ 调 用 g e t 方 法 ] 、 对 象 名 . 属 性 = [ 调 用 s e t 方 法 ] 对 象 名 . 方 法 ( ) ; 通过对象 类名 对象名 = new 类名(); 对象: 对象名.属性[调用get方法]、对象名.属性=[调用set方法] 对象名.方法(); =new();.[get].=[set].();

二.深入C#数据类型

数据类型

1、基本数据类型

1.包括的数据类型

数值:int,long,double,float
字符:char
布尔:bool
枚举:enum
结构:struct

2、命名空间:System.ValueType
3、保存方式:值保存在栈里面

2、引用数据类型

1.包括的数据类型

class(string)
数组
集合
委托
接口

2.命名空间:syste.Object;

3.值保存在堆里面

struct结构

(应用在静态动作比较多的情况)

1.定义

类似类,但struct是基本数据类型,而类是引用数据类型

​ .1使用关键字struct

​ .2字段不能赋初始值

​ .3不能手写无参构造函数

​ .4结构里有多少个字段,定义构造函数就要有多少个参数

2.struct的使用

​ .1可以new出来,也可以不new出来

[注意:如果不new直接赋初始值会语法报错]

​ .2结构在使用的时候要给所有字段赋初始值,不然会语法报错

示例:

public class StuClass
    {
        #region 构造函数---》方法,new对象用的,主要作用给字段赋值
        /// <summary>
        /// 作用:new对象的
        /// 如果不手写,那么会有一个默认的无参隐藏构造函数
        /// 一旦手写构造函数,不存在默认构造函数
        /// 构造函数:有参构造,无参构造函数
        /// java:
        /// Scanner in = new Scanner(System.in)
        /// String str = new String();
        /// String str = new String("sdf");
        /// </summary>
        public StuClass() { }
        #endregion

        #region 字段+属性
        private String _name = "asdf";

        public string Name { get => _name; set => _name = value; }
        #endregion

        #region 方法
        public void ShowInfo()
        {
            Console.WriteLine("自我介绍!");
        }
        #endregion
    }
    public struct StStruct
    {
        #region 构造函数
        //结构在使用的时候,所有字段必须赋值
        //定义构造函数的时候,必须给所有的字段赋值;不能手写无参构造函数
        //public StStruct() { }
        public StStruct(int age, String name)
        {
            this._age = age;
            this._name = name;
        }
        #endregion

        #region 字段+属性
        public int _age;
        //结构:不需要get、set属性
        public int Age { get => _age; set => _age = value; }
        //结构在定义字段时候不能有初始值
        //public String _name = "df"; 
        public String _name;
        public string Name { get => _name; set => _name = value; }
        #endregion

        #region 方法
        public void ShowInfo()
        {
            Console.WriteLine("自我介绍!");
        }
        #endregion
    }
3.注意使用的事项

​ 1、结构只保存栈
​ 2、如果字段太多,频繁相互指向,不建议
​ 如果没有字段,自己使用自己的值—》性能比较优化

​ 堆:空间大速度慢
​ 栈:空间小速度快

参数传递

1.值传递

​ 1.基本数据类型:形参所做改变不会影响实参

​ 2.引用数据类型:形参所做改变会影响实参[同一个堆里面],string除外

​ 同一个堆也就是 对象不能直接 用=值

​ 图片:
在这里插入图片描述

2.引用传递[地址传递]

​ 1.形参所做修改会影响实参

​ 2.形参和实参都要在前面加ref

​ 3.、加了ref,表示,当前变量,指针,指向前一个变量的地址

图片:

在这里插入图片描述

装拆箱

装箱:基本数据---》引用--->自动转换
int i = 0;
Object obj = i; 
拆箱:引用---》基本
Object obj = 100;
int i=Convert.ToInt32(obj);

示例;

 static void Main(string[] args)
        {
            Console.WriteLine("********************设置计算机ID前***********************");
            Console.WriteLine("计算机型号\t计算机ID\t购买时间");
            Computer[] computers = new Computer[3];

            Computer cm1 = new Computer();
            cm1.Type = "hpCQ-217TX";
            cm1.Datetime = "2013-10-5";
            computers[0] = cm1;

            Computer cm2 = new Computer();
            cm2.Type = "Mc240CH/A";
            cm2.Datetime = "2013-10-5";
            computers[1] = cm2;

            Computer cm3 = new Computer();
            cm3.Type = "SYNW18/W";
            cm3.Datetime = "2013-10-5";
            computers[2] = cm3;

            for (int i = 0; i < computers.Length; i++)
            {
                Console.WriteLine(computers[i].Type+"\t\t\t"+computers[i].Datetime);
            }
            Console.WriteLine();
            Console.WriteLine("********************设置计算机ID后***********************");
            Console.WriteLine("计算机型号\t计算机ID\t购买时间");
            Random rd = new Random();
            for (int i = 0; i < computers.Length; i++)
            {
                int sjshu = rd.Next(1000, 9999);
                computers[i].Id += computers[i].Type + "-" + sjshu;
                Console.WriteLine(computers[i].Type + "\t" +computers[i].Id+"\t"+ computers[i].Datetime);
            }
            Console.ReadLine();
        }

三.使用集合组织相关信息

基本定义:

1、集合:保存一组大小不固定的值
2、类似数组:

3、泛型跟非泛型:
泛型:限定了数据类型
非泛型:没有限定数类型

ArrayList

​ ArrayList:没有限定数据类型—>涉及到频繁的拆箱装箱,类型转换
​ 1、创建对象
​ ArrayList list = new ArrayList();
​ 2、属性:
​ Count–》得到长度
​ 3、方法:
​ Add(Object value)–>添加
​ RemoveAt(int index)–>移除的是下标
​ Remove(Object value)—>移除的是值
​ Clear()—>清空所有的
​ [int index]–>1、获取值;2、赋值【注意:下标一定是已经存在的】
​ 4、遍历

for
		   for(int i = 0; i < list.Count;i ++)
				{
					Object obj = list[i];
                    Console.WriteLine(obj );
				}
			foreach
				foreach(Object value in list)
                {

​				  Console.WriteLine(value );
​               }
List

​ List:限定了数据类型
​ 1、创建对象
​ List list = new List();
​ T:任意数据类型
​ List可以实现ArrayList的效果–》List也可以保存任意值
​ List

​ List list = new List(); //不放T数据类型,error,编译报错
​ 2、属性:
​ Count–》得到长度
​ 3、方法:
​ Add(Object value)–>添加
​ RemoveAt(int index)–>移除的是下标
​ Remove(Object value)—>移除的是值
​ Clear()—>清空所有的
​ [int index]–>1、获取值;2、赋值【注意:下标一定是已经存在的】
​ 4、遍历:

	
		for:
			for(int i = 0; i < list.Count; i++)
			{
				list[i]
			}
		foreach
			foreach(T value in list)
			{
				value
			}

示例:

 HealthCheckSet set;
        //采用泛型集合List保存所有的体检项目
        List<HealthCheckItem> AllItems = new List<HealthCheckItem>();

        //采用泛型集合List保存套餐中的体检项目
        List<HealthCheckItem> items = new List<HealthCheckItem>();
        #region 创建所有检查项目,并保存在AllItems集合中
        public void AllItemsd()
        {
            height = new HealthCheckItem("身高","用于检查身高",5);
            weight = new HealthCheckItem("体重","用于检查体重",5);
            Gang = new HealthCheckItem("肝","用于检查肝功能",50);
            B超 = new HealthCheckItem("B超","用于检查B超",30);
            ekg = new HealthCheckItem("心电图", "用于检查心电图", 50);
            bloodPressure = new HealthCheckItem("血压", "用于检查血压", 20);
            bloodTest = new HealthCheckItem("血常规","用于检查血常规", 20);
            AllItems.Add(height); 
            AllItems.Add(weight);
            AllItems.Add(Gang);
            AllItems.Add(B超);
            AllItems.Add(ekg);
            AllItems.Add(bloodPressure);
            AllItems.Add(bloodTest);
        }
        #endregion

        #region 创建一组默认套餐设置
        private void InerSet()
        {
            //创建1种默认套餐对象
            items = new List<HealthCheckItem>();
            items.Add(height);
            items.Add(weight);
            items.Add(B超); 
            set = new HealthCheckSet("入学体检", items);
            //计算套餐价格
            set.CalcPrice();
            this.HealthSet.Add("入学体检", set);
        }
        #endregion

        #region 加载体检套餐
        private void TjianTC()
        {
            this.cboSets.Items.Clear();
            this.cboSets.Items.Add("请选择");
            foreach (string  key in HealthSet.Keys)
            {
                this.cboSets.Items.Add(key);
            }
            this.cboSets.SelectedIndex = 0;
        }
        #endregion
        #region 加载事件
        private void frmMain_Load(object sender, EventArgs e)
        {
            this.lblSetName.Text = " ";
            this.lblSetPrice.Text = " ";
            this.btnAdd2.Enabled = true;
            this.btnClear.Enabled = true;
            AllItemsd();//创建所有检查项目,并保存在AllItems集合中
            InerSet();//创建一组默认套餐设置
            TjianTC();// 加载体检套餐
        }
        #endregion
        #region 更新套餐检查项目
        private void UpdateSet(HealthCheckSet set)
        {
            this.dgvTj.DataSource = new BindingList<HealthCheckItem>(set.Items);

        }
        #endregion
Hashtable

​ 1、创建对象
​ Hashtable ht = new Hashtable();
​ 2、属性
​ Count–》得到长度
​ Keys—>得到当前Hashtable里面所有的键
​ Values–>得到当前hashtabale里面所有的值
​ 3、方法
​ Add(Object key, Object value)
​ Remove(Object key)–>根据key移除
​ Clear()清空
​ 5、遍历:
​ 1、遍历所有key

     foreach(Object key in ht.Keys)
	{
		key +  ht[key]
	}

​ 2、遍历所有的value

      foreach(Object value in ht.Values) 
      {
          value
      }

​ 4、key是唯一

Dictionary

​ 1、创建对象
​ Dictionary<Tkey, Tvalue> dic = new Dictionary<TKey, Tvalue>();
​ 2、属性
​ Count–》得到长度
​ Keys—>得到当前Hashtable里面所有的键
​ Values–>得到当前hashtabale里面所有的值
​ 3、方法
​ Add(Object key, Object value)
​ Remove(Object key)–>根据key移除
​ Clear()清空
​ ContainsKey(TKey key);–》判断key是否已经存在,存在返回true
​ 5、遍历:
​ 1、遍历所有key

      foreach(T key in ht.Keys)
	  {
		 key +  ht[key]
	  }

​ 2、遍历所有的value

	foreach(T value in ht.Values) 
	{
	      value 
	}

​ 4、key是唯一
​ 3、null不能作为key,编译的报错,运行的时候

示例:

 //使用Dictionary字典保存套餐集合
        public Dictionary<string, HealthCheckSet> HealthSet = new Dictionary<string, HealthCheckSet>();

        #region 创建所有检查项目,并保存在AllItems集合中
        public void AllItemsd()
        {
            height = new HealthCheckItem("身高","用于检查身高",5);
            weight = new HealthCheckItem("体重","用于检查体重",5);
            Gang = new HealthCheckItem("肝","用于检查肝功能",50);
            B超 = new HealthCheckItem("B超","用于检查B超",30);
            ekg = new HealthCheckItem("心电图", "用于检查心电图", 50);
            bloodPressure = new HealthCheckItem("血压", "用于检查血压", 20);
            bloodTest = new HealthCheckItem("血常规","用于检查血常规", 20);
            AllItems.Add(height); 
            AllItems.Add(weight);
            AllItems.Add(Gang);
            AllItems.Add(B超);
            AllItems.Add(ekg);
            AllItems.Add(bloodPressure);
            AllItems.Add(bloodTest);
        }
        #endregion

        #region 创建一组默认套餐设置
        private void InerSet()
        {

            //创建1种默认套餐对象
            items = new List<HealthCheckItem>();
            items.Add(height);
            items.Add(weight);
            items.Add(B超); 
            set = new HealthCheckSet("入学体检", items);
            //计算套餐价格
            set.CalcPrice();
            this.HealthSet.Add("入学体检", set);
        }
        #endregion

自定义泛型:

作用:

​ 保证类里面的变量数据类型更加灵活

语法:

​ public class 类名
​ {
​ }

四.深入类的方法

重载

1.特点与运用

​ 1、在同一个类中
​ 2、相同的方法名
​ 3、不同的参数,或者个数不相同
​ 4、对应的参数下标的—》参数类型不同

​ 同类中方法后面的参数个数不同

​ 同类中方法后面的参数个数相同,数据类型不同

2、类的成员

​ 1、.同类中不能有相同名字的字段
​ 2、一般不能有相同的方法名,在重载状态下允许相同方法名

3、存在意义

​ 为了解决方法名太多的问题
​ void Add(int i, int j){}
​ void Add(int i, int j,int k){}

4、调用规则与注意事项

​ 根据参数[个数+类型]调用

【不能】以【返回值类型】来决定是否是重载
【不能】以【访问修饰符】来决定是否是重载

构造函数

1、语法和作用

​ 访问修饰符 类名(){}
​ 注意:
​ 1、类似方法,只是少了一个返回值
​ 2、方法名有要求:跟类名一致
​ 3、构造函数也是会被重载

​ 用来new对象,兼职:给成员变量赋值(作用)

2、分类

​ 显示方式:
​ 隐式:隐藏的无参
​ 1、就是创建一个类,没有手写构造函数的时候当前类自带的构造函数
​ 2、就是无参的构造函数
​ 显示:自定义构造
​ 就是自定义构造函数
​ 参数的格式:
​ 有参
​ 无参

3、特点(C#和Java)

​ 只要定了一个类:如果没有手写构造函数,那么这个类会自带一个无参的构造函数,并且这个构造函数比隐藏
​ 只要你手写了构造函数,那么这个类就不会存在隐藏构造函数【不会有默认的无参构造函数】

对象交互

​ 面向对象的方法

1.封装

隐藏实现细节,公开某种功能作为与外界的通信的通道

2.消息传递

​ 每个对象都有特定的功能 ,相对其它对象而言,它的功能就是为其它对象提供的服务

示例:

 public  class Client
    {
        public Client customer;//顾客
        public int id;
        public string mealLisst;
     }
  public  class Order
    {
        public Client customer;//顾客
        public int id;
        public string mealLisst;
    }
     public  class Waitress
    {
        private Order order;
        public void GetOrder(Order order)
        {
            this.order = order;
        }
     }

五.继承和多态

类的三大特性:

封装:将某个写类的内部信息私有化
继承:子类继承父类
多态:一个事务的多种形态

1、继承

继承的语法:

public class B : A
		{
			A:父类.基类
			B:子类,派生类
		}

概念:描述两个类之间的关系
父类/基类:被继承的类
子类/派生类:继承的类
通过new对象调用类里面的成员,只有public可以直接调用
一旦产生继承关系,子类里面可以直接使用父类里面所有【非private】成员
一旦继承了,new子类对象时,父类里面的成员的使用规则跟本类成员的使用规则是一样

默认访问修饰符:
			类的默认访问修饰符:internal
			类的成员的默认访问修饰符:private

1、每一个子类的构造函数一定会调用父类的构造函数
2、默认的情况下:调用的是父类的无参构造函数
也可以显示调用无参构造函数–》在形参的结束小括号后面::base()
3、也可以显示的调用父类的构造函数:

    :base()---》表示在调用父类的无参构造函数
	调用方法的时候一般有两个参数:
		实参
		形参
		:base(值)---》实参
4、关键字:
		base:调动父类的成员
		this:调用本类的成员

示例;


    //父类 工作类
    public abstract class Job
    {
        public string Type { get; set; }
        public string Name { get; set; }
        public string Descrpition { get; set; }
        public Job() { }
    
    //子类,编码工作类
    public class CodeJob : Job
    {
        public CodeJob(string type, string name, string desc) : base(type, name, desc) { }
        public CodeJob() { }
        public int CodingLines { get; set; }
        public int Bugs { get; set; }
        public int WorkDay { get; set; }
        public override void Execute()
        {
            frmBma bma = new frmBma(this);
            bma.ShowDialog();
        }
2、多态:

实现方式:

重载重写
前提:两个类存在继承关系两个类存在继承关系
特点1、在同一个类中
2、有相同的方法名
3、有不同的参数:个数不一样,或者对应下标的参数的数据类型不样
1、不同的类中
2、相同的方法
3、相同参数
调用规则匹配相同的参数个数
匹配对应下标的参数的类型
直接调用
实现方式方法后面参数类型或者个数不同虚方法:virtual+override
抽象方法:abstract+override
 //父类
    public abstract   class Job
    {
        public string Type { get; set; }
        public string Name { get; set; }
        public string Descrpition { get; set; }
        public Job() { }
        public Job(string type,string name, string descrpition)
        {
            this.Name = name;
            this.Type = type;
            this.Descrpition = descrpition;
        }
        public abstract void Execute();
    }
 //子类的抽象方法
   public class CodeJob:Job
    {
        public CodeJob(string type, string name, string desc) : base(type, name, desc) { }
        public CodeJob() { }
        public int CodingLines { get; set; }
        public int Bugs { get; set; }
        public int WorkDay { get; set; }
        public override void Execute()
        {
            FrmCodeExe frmCodeExe = new FrmCodeExe();
            frmCodeExe.ShowDialog();
        }
    }
内容概要:本文详细介绍了如何利用Simulink进行自动代码生成,在STM32平台上实现带57次谐波抑制功能的霍尔场定向控制(FOC)。首先,文章讲解了所需的软件环境准备,包括MATLAB/Simulink及其硬件支持包的安装。接着,阐述了构建永磁同步电机(PMSM)霍尔FOC控制模型的具体步骤,涵盖电机模型、坐标变换模块(如ClarkPark变换)、PI调节器、SVPWM模块以及用于抑制特定谐波的陷波器的设计。随后,描述了硬件目标配置、代码生成过程中的注意事项,以及生成后的C代码结构。此外,还讨论了霍尔传感器的位置估算、谐波补偿器的实现细节、ADC配置技巧、PWM死区时间换相逻辑的优化。最后,分享了一些实用的工程集成经验,并推荐了几篇有助于深入了解相关技术优化控制效果的研究论文。 适合人群:从事电机控制系统开发的技术人员,尤其是那些希望掌握基于Simulink的自动代码生成技术,以提高开发效率控制精度的专业人士。 使用场景及目标:适用于需要精确控制永磁同步电机的应用场合,特别是在面对高次谐波干扰导致的电流波形失真问题时。通过采用文中提供的解决方案,可以显著改善系统的稳定性性能,降低噪声水平,提升用户体验。 其他说明:文中不仅提供了详细的理论解释技术指导,还包括了许多实践经验教训,如霍尔传感器处理、谐波抑制策略的选择、代码生成配置等方面的实际案例。这对于初学者来说是非常宝贵的参考资料。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值