【C#进阶】C#语法中一些常用知识点总结

文章目录

    • 1.三目运算符
    • 2.循环控制语句 (for while do…while foreach)
    • 3.访问修饰符
    • 4.静态方法和非静态方法
    • 5.数组、字典和其他集合类型
      • 1. 数组(Array)
      • 2. 列表(List)
      • 3. 字典(Dictionary)
      • 4. 队列(Queue)
      • 5. 栈(Stack)
      • 6. 散列集(HashSet)
      • 总结一下
    • 6. out和ref
    • 7.属性和变量
    • 8.构造函数
    • 9.面向对象(封装、继承、多态)
    • 10.接口(Interface)
    • 11.抽象类

很久没有用写C#代码了,最近花了点时间重温了一下C#语法的一些知识点,查缺补漏!

1.三目运算符

//三目运算符:?:
//如 a>0?1:2
int a = -1;
// 通过?以及:将表达式分为3部分
var result = a > 0 ? 1 : 2;
// ?号前表示条件,得到一个bool值,如果为真,返回:号前面的结果,否则返回:号后面的结果 
Console.WriteLine(result);// 当a>0  返回1
// 当a<0  返回2
// 否则   返回0

代码示例:

a = 1;
result = a > 0 ? 1 : (a < 0 ? 2 : 0);//1
Console.WriteLine(result);
a = -1;
result = a > 0 ? 1 : (a < 0 ? 2 : 0);//2
Console.WriteLine(result);
a = 0;
result = a > 0 ? 1 : (a < 0 ? 2 : 0);//0
Console.WriteLine(result);

2.循环控制语句 (for while do…while foreach)

// 针对数据集合进行遍历
int[] values = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Console.WriteLine(values);
for (int i = 0; i < values.Length; i++)
{// i:0 1 2 3 4 5 6 7 8    //   0   2   4   6   8if (i % 2 == 0)Console.WriteLine(values[i]);if (i % 2 > 0) continue;Console.WriteLine(values[i]);// break : 跳转循环,循环终止// continue : 结当次循环(后面的代码不执行了),直接执行下次循环
}int index = 0;
// foreach:遍历每一个元素
foreach (int i in values)
{Console.WriteLine(i);index++;
}// while :首先判断条件,条件满足进入循环。可能一次都执行不了
index = 5;
while (index < 5)
{// 死循环 index < 5一直为TrueConsole.WriteLine("Hello");index++;
}
Console.WriteLine("while结束");// do..while   选择执一遍,再判断条件,条件满足,继续执行,不满足即跳出。至少可以执一次
index = 5;
do
{Console.WriteLine("Hello");index++;
} while (index < 5);

3.访问修饰符

你可以把访问修饰符想象成一个家庭的不同房间和钥匙。public就像是客厅,任何人都可以进入。private是你的私人房间,只有你自己可以进入。protected像是家庭成员共用的房间,只有家庭成员(派生类)可以进入。internal则是整个家(同一程序集)的公共空间,只要是住在这个家里的人都可以进入。protected internalprivate protected则是钥匙的组合,给予更多灵活的访问控制。

  1. public:完全公开的。同一程序集中的任何其他代码或引用该程序集的其他程序集都可以访问该类型或成员。 某一类型的公共成员的可访问性水平由该类型本身的可访问性级别控制。(访问级别 = 0)
  2. private:只有同一 class 或 struct 中的代码可以访问该类型或成员。(访问级别 = 5)
  3. protected:只有同一 class 或者从该 class 派生的 class 中的代码可以访问该类型或成员。(访问级别 = 4)
  4. internal:同一程序集中的任何代码都可以访问该类型或成员,但其他程序集中的代码不可以。(访问级别 = 3)
  5. protected internal:该类型或成员可由对其进行声明的程序集或另一程序集中的派生 class 中的任何代码访问。(访问级别 = 2)
  6. private protected:该类型或成员可以通过从 class 派生的类型访问,这些类型在其包含程序集中进行声明。(访问级别 = 1)

4.静态方法和非静态方法

假设一个类是一个“房子”的蓝图。静态方法就像是这个蓝图上标注的固定信息,比如房屋的总平方尺数——你不需要建造一个实际的房子(实例化一个对象)来获取这个信息。非静态方法则像是房子里的开关或电器,你需要进入一个实际的房子(创建一个对象)来操作它们。

静态方法: 静态方法属于类本身,而不是类的实例。因此,无需创建类的实例就可以调用静态方法, 使用static关键字进行定义。

  • 访问限制:静态方法不能访问类的非静态成员。
  • 状态保持:静态方法不能使用或更改非静态字段,因为它们不依赖于对象状态。
  • 扩展性:不能被继承或重写。
  • 用途:通常用于实现不依赖于对象状态的功能,例如工具函数。

非静态方法: 非静态方法属于类的实例。需要先创建类的对象,然后才能调用这些方法。通常不需要特殊关键字,除非用于继承或重写等特殊情况。

  • 访问限制:非静态方法可以访问类中的所有成员。
  • 状态保持:可以使用或更改对象的状态(字段)。
  • 扩展性:可以被继承和重写。
  • 用途:通常用于实现依赖于或更改对象状态的功能。

5.数组、字典和其他集合类型

  • 数组:就像一列有固定数量的停车位,每个停车位只能停一辆特定类型的车。
  • 列表:更像一个动态的停车场,可以根据需要增加或减少停车位。
  • 字典:就像一个大楼的邮箱,每个邮箱有唯一的标签和里面的邮件。
  • 队列:就像排队等候,先来的先得到服务。
  • :就像一叠盘子,最后放上去的盘子会先被取下。
  • 散列集:就像一个房间里的人,每个人都是唯一的,但你不能预测他们站在房间里的哪个位置。

1. 数组(Array)

  • 定义方式: 使用方括号 []

  • 特性: 长度固定,元素类型相同。

  • 访问: 使用索引,从 0 开始。

  • 示例:

    int[] numbers = new int[5] {1, 2, 3, 4, 5};
    
  • 常用操作: Length 获取长度, SetValueGetValue 设置和获取值。

2. 列表(List)

  • 定义方式: 使用 List<T> 类。

  • 特性: 动态大小,元素类型相同。

  • 访问: 使用索引,从 0 开始。

  • 示例:

    List<int> numbers = new List<int> {1, 2, 3, 4, 5};
    
  • 常用操作: Add, Remove, Count, Contains

3. 字典(Dictionary)

  • 定义方式: 使用 Dictionary<TKey, TValue> 类。

  • 特性: 键值对存储,键唯一。

  • 访问: 使用键。

  • 示例:

    Dictionary<string, int> age = new Dictionary<string, int>
    {{"Alice", 30},{"Bob", 40}
    };
    
  • 常用操作: Add, Remove, ContainsKey, TryGetValue

4. 队列(Queue)

  • 定义方式: 使用 Queue<T> 类。

  • 特性: 先进先出(FIFO)。

  • 访问: 不能使用索引。

  • 示例:

    Queue<int> numbers = new Queue<int>();
    
  • 常用操作: Enqueue, Dequeue, Peek, Count

5. 栈(Stack)

  • 定义方式: 使用 Stack<T> 类。

  • 特性: 后进先出(LIFO)。

  • 访问: 不能使用索引。

  • 示例:

    Stack<int> numbers = new Stack<int>();
    
  • 常用操作: Push, Pop, Peek, Count

6. 散列集(HashSet)

  • 定义方式: 使用 HashSet<T> 类。

  • 特性: 元素唯一,无序。

  • 访问: 不能使用索引。

  • 示例:

    HashSet<int> numbers = new HashSet<int> {1, 2, 3};
    
  • 常用操作: Add, Remove, Contains, Count

总结一下

类型长度是否固定元素是否唯一是否有序可通过索引访问使用场景
数组固定大小
列表动态内容
字典键是否(通过键访问)配置设置
队列是(FIFO)打印队列、等待列表
是(LIFO)撤销操作、深度优先搜索
散列集停止词、唯一标识符集

6. out和ref

假设你要从一个魔法店里取出一些物品。

  • 使用 out 就像是你给店主一个空袋子,店主一定会在里面放一些东西。
  • 使用 ref 就像是你给店主一个已经有东西的袋子,店主可以查看里面的东西,也可以添加或更改里面的东西。

out 参数用于从方法返回多个值。使用 out 参数时:

  1. 在方法内必须为 out 参数赋值。
  2. 调用方法时,传入的变量不需要预先赋值。
public void GetData(out int x, out string y)
{x = 10;y = "hello";
}// 调用
int a;
string b;
GetData(out a, out b); //此时a=10,b="hello"

ref 参数用于双向传递。即:

  1. 在方法内可以访问 ref 参数的初始值。
  2. 在方法内可以更改 ref 参数的值,该更改将反映到外部变量。
  3. 调用方法时,传入的变量必须预先赋值。
public void ModifyData(ref int x)
{x = x * 2;
}// 调用
int a = 5;
ModifyData(ref a);  // a 现在是 10

7.属性和变量

变量(也称为字段)是类、结构或枚举中定义的成员,用于存储数据。它们可以有访问修饰符(如 public, private 等)。

public class MyClass
{public int MyField;  // 公有字段private string anotherField;  // 私有字段
}

属性提供了一种封装字段的方式,允许你通过 getset 访问器来控制字段的读取和写入。这有助于实现更好的数据封装和验证逻辑。

public class MyClass
{public int MyProperty_0 { get; set; }public int MyProperty_1 { get; }// 只有get没有set,表示这个属性是只读public int MyProperty_2 { get; private set; } //外部不可修改//public int MyProperty_2 { set; }// 不允许只写不读//更灵活的写法private int _myField;  // 私有字段public int MyProperty  // 公有属性{get { return _myField; }set{if (value >= 0) //进行更多操作_myField = value;}}
}

8.构造函数

构造函数就像是产品(对象)出厂时的“初始化设置”过程。在这个过程中,工厂(构造函数)会根据需求(参数)来设置产品(对象)的各种特性和功能(字段和属性)。

public class Person
{public string Name { get; set; }public int Age { get; set; }public Person(string name, int age) //构造函数{this.Name = name;this.Age = age;}
}
// 使用
Person person = new Person("Alice", 30);

一个类可以拥有多个构造函数,这被称为构造函数重载

public class Person
{public string Name { get; set; }public int Age { get; set; }public string Email { get; set; }// 无参数的构造函数public Person(){Name = "Unknown";Age = 0;Email = "unknown@example.com";}// 接受一个参数的构造函数public Person(string name){Name = name;Age = 0;Email = "unknown@example.com";}// 接受两个参数的构造函数public Person(string name, int age){Name = name;Age = age;Email = "unknown@example.com";}// 接受三个参数的构造函数public Person(string name, int age, string email){Name = name;Age = age;Email = email;}
}// 使用无参数构造函数
Person person1 = new Person();// 使用一个参数的构造函数
Person person2 = new Person("Alice");// 使用两个参数的构造函数
Person person3 = new Person("Bob", 30);// 使用三个参数的构造函数
Person person4 = new Person("Charlie", 40, "charlie@example.com");

9.面向对象(封装、继承、多态)

  1. 封装(Encapsulation)

    • 封装是将数据(字段)和相关操作(方法)封装在一个类中的概念。这可以通过访问修饰符(如publicprivateprotected)来实现,以控制数据的访问级别,防止直接访问内部数据。

    • 这有点像手机的外壳,你可以使用屏幕、按钮等接口来与手机交互,但不能直接触及手机内部的电路。

    • 例子:

      public class Person
      {private string name;private int age;public string GetName(){return name;}public void SetName(string newName){name = newName;}public int GetAge(){return age;}public void SetAge(int newAge){if (newAge >= 0){age = newAge;}}
      }
      //name和age字段被封装在Person类中,并通过公有方法GetName()、SetName()、GetAge()和SetAge()来访问和修改它们,防止直接访问字段。
      
  2. 继承(Inheritance)

    • 允许一个类(子类)继承另一个类(父类)的成员(字段和方法),并且可以在子类中添加新成员或重写父类的成员。
    • 想象一下家庭中的关系,孩子可以继承父母的一些遗传特征,如眼睛颜色,同时也可以拥有自己独特的特征。
    • 例子:
    public class Vehicle
    {public string Make { get; set; }public string Model { get; set; }public void StartEngine(){Console.WriteLine("Engine started.");}
    }public class Car : Vehicle
    {public int Year { get; set; }public void Accelerate(){Console.WriteLine("Car is accelerating.");}
    }
    //在这个例子中,Car类继承了Vehicle类的Make、Model属性和StartEngine()方法,并且添加了自己的属性Year和方法Accelerate()。
    
  3. 多态(Polymorphism)

    • 允许不同的对象对相同的方法做出不同的响应。这可以通过方法重写和接口来实现。
    • 这就像电器插座适配器,不同的电器可以插入同一个插座,但它们在插座中的表现不同。
    • 例子:
    public class Animal
    {public virtual void MakeSound(){Console.WriteLine("Some generic animal sound.");}
    }public class Dog : Animal
    {public override void MakeSound(){Console.WriteLine("Woof! Woof!");}
    }public class Cat : Animal
    {public override void MakeSound(){Console.WriteLine("Meow!");}
    }
    //Animal类有一个虚拟方法MakeSound(),Dog和Cat类分别重写了这个方法,使得它们可以表现出不同的声音。其中还使用virtual 和 override 关键字是一种明确的方式来声明和表达方法的重写关系,有助于代码的可读性和维护性。
    

10.接口(Interface)

  1. 定义方式:使用interface关键字。
  2. 成员:只能包含方法、属性、事件和索引器的声明,不能包含实现。
  3. 访问修饰符:所有成员自动为public,不允许添加其他访问修饰符。
  4. 多继承:一个类可以实现多个接口。
  5. 实现:实现接口的类必须提供接口中所有成员的实现。

示例:

1.定义接口

//假设正在开发一个绘图程序,需要支持多种图形(如圆形、矩形等)。可以定义一个IDrawable接口:
interface IDrawable
{void Draw();
}

2.实现接口定义类

//定义不同的图形类,如Circle和Rectangle,并实现IDrawable接口:
class Circle : IDrawable
{public void Draw(){Console.WriteLine("Drawing a circle.");}
}class Rectangle : IDrawable
{public void Draw(){Console.WriteLine("Drawing a rectangle.");}
}

3.使用

IDrawable[] drawables = new IDrawable[] { new Circle(), new Rectangle() };
foreach (var drawable in drawables)
{drawable.Draw();
}
//Drawing a circle.
//Drawing a rectangle.

11.抽象类

  1. 定义方式:使用abstract关键字。
  2. 成员:可以包含字段、方法、属性、事件和索引器。方法可以有或没有实现。
  3. 访问修饰符:成员可以有不同的访问修饰符(publicprotected等)。
  4. 多继承:一个类只能继承一个抽象类。
  5. 实现:继承抽象类的子类必须实现所有抽象成员。

示例:

1.定义抽象类

public abstract class Shape
{public abstract void Draw();  // 抽象方法public void Move()  // 具体方法{Console.WriteLine("Moving the shape.");}
}

2.继承抽象类

//定义Circle和Rectangle类,并继承Shape:
class Circle : Shape
{public override void Draw(){Console.WriteLine("Drawing a circle.");}
}class Rectangle : Shape
{public override void Draw(){Console.WriteLine("Drawing a rectangle.");}
}

3.使用

Shape[] shapes = new Shape[] { new Circle(), new Rectangle() };
foreach (var shape in shapes)
{shape.Draw();shape.Move();
}
//Drawing a circle.
//Moving the shape.
//Drawing a rectangle.
//Moving the shape.

精彩推荐:
【C#进阶一】C#中的数组(Array)、集合(ArrayList,Queue,Stack, HashList)、List<T>、字典(Dictionary<K,T>)和双向链表LinkedList
【C#进阶八】C#中的序列化与反序列化下(二进制序列化、XML序列化及JSON序列化)

希望有所帮助,同时欢迎关注我,后面将更新更多相关内容!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/116961.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

EtherCAT从站转modbus RTU协议转换网关用modbus slave测试的方法

远创智控YC-ECT-RTU通讯网关具有EtherCAT从站功能&#xff0c;主要功能是将EtherCAT网络和Modbus-RTU网络连接起来。在使用方面&#xff0c;本网关可以连接到EtherCAT总线中作为从站使用&#xff0c;也可以连接到Modbus-RTU总线中作为主站或从站使用。这款通讯网关还支持多种不…

c++ qt连接操作sqlite

qt客户端编程,用到数据库的场景不多,但是部分项目还是需要数据库来保存同步数据,客户端用到的数据库,一般是sqlite。 Qt提供了数据库模块,但是qt本身的数据库模块并不好用,会有各种问题, 建议大家不要,可以自己封装数据库的操作。本篇博客介绍qt连接操作sqlite。 sqlit…

nmp、yarn、yeoman、bower是什么东西?

1&#xff1a;npm&#xff08;Node Package Manager&#xff09;&#xff1a;npm 是 Node.js 的包管理器&#xff0c;用于安装、管理和共享 JavaScript 包。它是 JavaScript 生态系统中最常用的包管理工具&#xff0c;可以轻松地安装和管理项目的依赖项。 2&#xff1a;Yarn&a…

【python VS vba(系列2)】 python和vba读写EXCEL文件的方式比较 (建设ing)

目录 1 用VBA读写EXCEL文件 1.1 用VBA读写&#xff0c;本工作簿workbook里的特定sheet的特定内容 1.1.1 EXCEL表内内容访问 1.1.2 注意点 1.1.3 代码 1.2 用VBA读写本工作簿workbook里的所有sheet的内容 1.2.1 麻烦之处 1.2.2 方法&#xff0c;如何指定EXCEL里的内容…

【珠峰 WEB 前端架构师课程】学习笔记 100 篇(完结)

该课程是珠峰姜文老师讲的&#xff0c;个人觉得讲的很不错&#xff0c;一路在 b 站学习下来做了 100 篇的学习笔记&#xff0c;收获颇丰。 该课程主要讲了高阶函数、函数柯里化、发布订阅模式、观察者模式、从 0 到 1 实现一个 promise&#xff0c;co 库的实现、eventloop 执行…

apk反编译修改教程系列-----任意修改apk版本号 版本名 防止自动更新【二】

往期教程 apk反编译修改教程系列-----修改apk应用名称 任意修改名称 签名【一】 上期演示了下如何修改apk的名称。相信只要用心的友友都会操作了。这次讲解下如何修改软件的版本号与版本名字的操作 名词浅释&#xff1a; 在apk反编译中的VersionCode---是版本号的意思.是一…

Vue3 实现页面简单的CRUD

请求拦截器 import axios from axios; import { ElNotification, ElMessageBox, ElMessage, ElLoading } from element-plus; import { saveAs } from file-saver; import store from /store; import { getToken } from /utils/token; import errorCode from /utils/errorCode…

基于斑点鬣狗算法的无人机航迹规划-附代码

基于斑点鬣狗算法的无人机航迹规划 文章目录 基于斑点鬣狗算法的无人机航迹规划1.斑点鬣狗搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用斑点鬣狗算法来优化无人机航迹规划。 …

LuatOS-SOC接口文档(air780E)-- ioqueue - io序列操作

ioqueue.init(hwtimer_id,cmd_cnt,repeat_cnt) 初始化一个io操作队列 参数 传入值类型 解释 int 硬件定时器id&#xff0c;默认用0&#xff0c;根据实际MCU确定&#xff0c;air105为0~5&#xff0c;与pwm共用&#xff0c;同一个通道号不能同时为pwm和ioqueue int 一个完…

Java 基础 面试 多线程

1.多线程 1.1 线程&#xff08;Thread&#xff09; 线程时一个程序内部的一条执行流程&#xff0c;java的main方法就是由一条默认的主线程执行 1.2 多线程 多线程是指从软硬件上实现的多条执行流程的技术&#xff08;多条线程由CPU负责调度执行&#xff09; 许多平台都离不开多…

【Matlab笔记_17】查找数组中相同元素

案例一&#xff1a;找到数组中相同元素所在位置索引 方法&#xff1a;使用unique函数用于找到唯一的元素和它们在原数组中的索引。然后&#xff0c;histc函数用于计算每个唯一元素的出现次数&#xff0c;并通过ismember函数找到重复元素在原数组中的索引。最后&#xff0c;通过…

动手学深度学习—网络中的网络NiN(代码详解)

目录 1. NiN块2. NiN模型3. 训练模型 LeNet、AlexNet和VGG都有一个共同的设计模式&#xff1a; 通过一系列的卷积层与汇聚层来提取空间结构特征&#xff1b;然后通过全连接层对特征的表征进行处理。 如果在过程的早期使用全连接层&#xff0c;可能会完全放弃表征的空间结构。 …

Day 1 Vue 页面框架

现在前端框架越来越像后端了&#xff0c;特别是TypeScript这样的语言出现后&#xff0c;开发前端的体验跟后端渐渐接近了。当然&#xff0c;作为一个后端&#xff0c;直接上手前端&#xff0c;还是有很多坑要填的。 本次开发&#xff0c;前端页面框架直接选择Vue。原因很简单&…

深入浅出排序算法之归并排序

目录 1. 归并排序的原理 1.1 二路归并排序执行流程 2. 代码分析 2.1 代码设计 3. 性能分析 4. 非递归版本 1. 归并排序的原理 “归并”一词的中文含义就是合并、并入的意思&#xff0c;而在数据结构中的定义是将两个或者两个以上的有序表组合成一个新的有序表。 归并排序…

Python-pptx教程之一从零开始生成PPT文件

简介 python-pptx是一个用于创建、读取和更新PowerPoint&#xff08;.pptx&#xff09;文件的python库。 典型的用途是根据动态内容&#xff08;如数据库查询、分析数据等&#xff09;&#xff0c;将这些内容自动化生成PowerPoint演示文稿&#xff0c;将数据可视化&#xff0c…

hutool 工具类提高编码效率

hutool 工具类 hutool 依赖 引入 hutool 依赖包。 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.6</version> </dependency>StrUtil 常用方法&#xff1a; StrUtil.equals&…

【IDEA配置】IDEA配置

参考视频&#xff1a;【idea必知必会】优化设置 告别卡顿 1. 显示内存 右击底下空白区域&#xff0c;出现memory indicator内存指示器&#xff0c;点击勾选即可显示。有的是在Settings->Appearance->Window Options里&#xff0c;如图所示&#xff1a; 2. 内存设置 …

虚拟世界游戏定制开发:创造独一无二的虚拟体验

在游戏开发领域&#xff0c;虚拟世界游戏定制开发是一项引人注目的任务&#xff0c;旨在满足客户独特的需求和愿景&#xff0c;创造一个完全个性化的虚拟世界游戏。这种类型的游戏开发需要专业的技能、深刻的游戏开发知识和密切的与客户合作&#xff0c;以确保游戏满足客户的期…

数据库Redis(二):基本数据类型

Redis中采用Key-Value键值对的形式将数据存储在数据库中&#xff0c;首先介绍Redis中针对键Key的操作命名。 Redis键Key相关命令 # 查看当前库所有key keys * # 判断某个key是否存在 exists <key> # 查看你的key是什么类型 type <key> # 删除指定的key数据 …

uboot移植之环境变量bootargs

一. 简介 uboot 中有两个非常重要的环境变量 bootcmd 和 bootargs。本文来学习 uboot的环境变量 bootargs。 bootargs 环境变量也叫命令行参数。bootargs 保存着 uboot 传递给 Linux 内核的参数。 二. uboot移植之环境变量bootargs 环境变量 bootargs 的设置是在 mx6ull_al…