创建项目流程
- 项目模板选择 ----- 控制台应用(NET Framework)
- 创建项目流程
- 项目名称可以先选择默认,选择好NET框架版本后直接点击创建项目
不出意外的话,点击创建项目,我们的Vs Studio就会打开项目
项目文件介绍
首先映入眼帘的应该是vs studio开发界面,此时往右看你会看到项目的展开列表
我们只需要关心 Program.cs 这是执行类文件,点击vs studio顶部的启动,运行的就是Program.cs文件内容
注意:
cs文件就是 Csharp文件
点击启动:
当然这是我写了一部分内容,终端才会输出一些东西,你看到的应该是全黑,闪一下就会退出
C# 的代码结构
C# 代码结构: 命名空间 | 类 | 方法
变量类型介绍
变量类型 | 解释 |
string | 字符串类型,用于表示一串字符序列。字符串是不可变的,即不能在原有字符串上进行修改,而只能通过创建新的字符串来进行字符串操作。字符串类型在处理文本、用户输入、日志记录等方面非常常见和重要。 |
int | 整数类型,用于表示整数值。它可以存储正、负和零值。int类型通常用于计数、计算等需要使用整数的场景。它的取值范围为 -2,147,483,648 到 2,147,483,647。 |
double | 双精度浮点数类型,用于表示带有小数部分的数值。它可以存储更大范围的数值且精度更高。double类型适用于需要更高精度的数值计算,例如科学、工程和金融领域。 |
bool | 布尔类型,用于表示逻辑值。它只有两个可能的值:true(真)和false(假)。bool类型常用于条件判断和逻辑控制,例如if语句和循环语句。 |
char | 字符类型,用于表示单个字符。它可以存储任何Unicode字符。char类型通常用于处理单个字符的情况,例如字符处理、密码掩码等。 |
decimal | 十进制类型,用于表示精确的数值。它适用于进行财务和货币计算,因为它可以提供较高的精度。decimal类型存储的范围比double类型小,但是在保留小数点位置和精确计算方面更可靠。 |
DateTime | 日期和时间类型,用于表示特定的日期和时间值。DateTime类型可以存储日期和时间,例如记录时间戳、计划任务等。它提供了许多有用的方法和属性,以便进行日期和时间的操作和计算。 |
数组 (Array) | 数组是一种数据结构,用于存储固定大小的相同类型元素的集合。使用数组,可以按照索引访问和操作集合中的元素。数组在存储和处理大量数据时非常有用。 |
可能有些晦涩难懂,但是不用怕!老夫毕竟也不是魔鬼,怎么可能让你们看不懂,就先记住
string
|int
|bool
这三个就好了~ 🤑
简单的语法介绍
接下来我会简单的介绍一下某些我们即将用到的部分语法,为c#学习之路做简单的铺垫
API/关键字 | 解释 |
using | using 是一个关键字,用于引入命名空间(namespace)或声明可回收资源对象,这篇博客我们只介绍命名空间的引入,在源文件中引入一个或多个命名空间,以便在代码中直接使用其中的类型和成员,而无需每次都完整写出命名空间的名称(例如引入控制台扩展程序啊…dll文件,下面会详细介绍dll文件的用法) |
Console.WriteLine() | 用于输出内容 |
Console.ReadKey() | 是C#中 Console 类的一个方法,用于从控制台窗口读取用户的单个按键输入 |
Console.ReadLine() | 是C#中 Console 类的一个方法,用于从控制台窗口读取用户的输入 |
var | 声明变量,任何类型(var n = 1;) |
打印内容
标准第一步:HelloWorld
using System; // 引入C#官方写好的System nameSpace,当然你写Console.WriteLine的时候可能他就自动给你补全了=w= namespace ConsoleApp1 // 命名空间 { class Program // 删减 internal,暂不介绍 { static void Main(string[] args) // Main方法为入口函数 { Console.WriteLine("helloWorld"); // 输出 Console.ReadKey(); // 监听键盘API,按下任意一个键退出终端,如果不加上这个,程序闪一下就会自动退出 } } }
然后点击启动,你会看到这样的画面…
看!打印出了Hello World
!我已经精通Csharp了!()
然后按下键盘任意一个键回退出终端窗口,此时监听的是 Console.ReadKey()
;
如果你以上步骤操作成功,恭喜你,你已经成功步入了Csharp开发这条不归路。😏
控制台输入
来来来,既然做完了第一个输出内容,那就趁热打铁来做第二个小案例
第二个小案例利用了 Console.WriteLine()
, Console.ReadKey()
, Console.ReadLine()
, 这三个API,请问阁下该如何应对呢?
开个小玩噱,看代码!
using System; namespace ConsoleApp1 { internal class Program { static void Main(string[] args) { // ------------------------------------------------------------------ // 名称收集 Console.WriteLine("请输入你的姓名: "); string name = Console.ReadLine(); // 故乡收集 Console.WriteLine("请输入你的故乡: "); string address = Console.ReadLine(); // 爱好收集 Console.WriteLine("请输入你的爱好: "); string hobby = Console.ReadLine(); // ------------------------------------------------------------------ if (name == "张三") { Console.WriteLine("法外狂徒:" + name); } else { Console.WriteLine("名字:" + name); } address = "dont"; hobby = "哈哈"; // ------------------------------------------------------------------ Console.WriteLine("故乡:" + address); Console.WriteLine("爱好: " + hobby); Console.ReadKey(); // ------------------------------------------------------------------ } } }
我已经贴心的把这段代码分为了三段,分别是
监听输入
|判断内容 修改内容
|输出内容
可能有些同志就不理解了啊,博主你偷袭60多岁的老同志,这个
if
和else
是个什么东西啊?诶!我大意了,没闪,接下来先给大家介绍一下
if
else
在c#
中的作用
int a = 1; // if 在众多开发语言内都是判断语句是否达到标准,从而执行一套执行标准或执行不标准判断的一种表现形式 if(a == 1) { // 如果... // 执行代码区 Console.WriteLine("我是1"); } else { // 不然... // 执行代码区 Console.WriteLine("我不是1"); } if(判断条件) { // 如果... // 执行代码区 } else { // 不然... // 执行代码区 }
咳咳,好了我们说回正题
- 关于上面那个小案例,我们首先在控制台输出了一些辅助性的文字,让用户输入
姓名
故乡
爱好
- 然后使用了
变量类型 变量名称 = Console.ReadLine();
来接收输入的内容 - 然后我们使用了
if
else
分别判断了name输入的是否是"张三"
如果是则执行if
内的代码,不是则执行else
内的代码,然后我们修改了address
hobby
的值 - 最后我们输出了用户输入的
故乡
爱好
点击启动,在输入姓名
故乡
爱好
之后,它看起来是这样的
如果这个案例也成功,那恭喜你,这可真是泰裤辣!
输入操作进行数据处理
经过前面的练习,应该已经对c#基础语法有了一定的认知,接下来进行简单的数据处理操作
将 用户输入的值
与 定义的值
进行相加操作
using System; namespace ConsoleApp1 { internal class Program { static void Main(string[] args) { Console.WriteLine("请输入一个数字:"); // 读取用户的输入 string str = Console.ReadLine(); int num = int.Parse(str) + 20; // c#中有数据运算(+ - * /)... // string num = str + 20.ToString(); // string num = str + 20; Console.WriteLine(num); Console.ReadKey(); } } }
以上代码会有几处陌生的地方,例如 int.Parse(str)
, 20.ToString()
int.Parse(str)
通过源码可以看到 Parse 也是 System nameplace的一个方法
此方法用于将字符串转换为整数数据类型 int 的方法,接受一个参数,如果可转换,例如输入的值为
"100"
,那么此方法会为你将string类型
的100转换为int类型
的100,若不能成功编译,则 C# 会抛出一个System.FormatException
的异常,其意义为:表示格式错误的异常情况
, 表示输入的字符无法像预期的格式被解析
ToString()
ToString 是一个将指定对象转换为字符串的方法
方法
static 我们在这里先不做表述
下方代码的具体逻辑是:
首先我们在入口函数Main中调用了一个方法,调用下方 void GetUserInf() {}, 此方法内让我们输入了姓名,又调用了
ChangeData()
每个方法都可以进行传值或接收某几个值, 进行相对应的操作,
ChangeData(string name1)
方法就是如此,我们常常把方法内的参数称之为形参
,意为:形式上的参数
,可以理解用来占位,我们把在GetUserInfo()
方法中调用的ChangeData(name)
中的name
称之为实参
, 指的是他实际接收到了一个定义的参数,ChangeData()
方法中又对name
进行了判断,若用户输入的是"张三"
, 则执行if
代码块,反之则执行else
代码块内容
若不理解也没有关系,写多了自然就理解了,不要急于一时
using System; namespace ConsoleApp1 { class Program { static void Main(string[] args) { // 调用方法 GetUserInfo(); } static void GetUserInfo() { Console.WriteLine("请输入你的姓名:"); string name = Console.ReadLine(); Console.WriteLine("name=" + name); string new_name = ChangeData(name); Console.WriteLine("传值方法name=" + new_name); Console.ReadKey(); } static string ChangeData(string name1) { if (name1 == "张三") { Console.WriteLine("法外狂徒" + name1); } else { Console.WriteLine("别的姓名"); } return name1; } } }
循环
主要介绍
for
循环 以及foreach
循环,另外还有多种循环,例如:while循环
,循环逻辑都是相同的
using System; namespace ConsoleApp1 { class Program { static void Main(string[] args) { // 循环 for (var i = 0; i < 10; i++) { Console.WriteLine(i.ToString()); Console.ReadKey(); } // 也可以写为 // foreach (var item in args) // { // Console.WriteLine(item.ToString()); // Console.ReadKey(); // } } } }
for 的语法解构
for(定义变量索引, 进行逻辑判断, 每一次循环都需要做什么) { // 根据你的需求写代码 }
这里可以把 i
比做成 10以内的每一个数,当 i
的索引为 0
时, i
第一次循环就是 在索引 0
的位置, 就是在第一个值得位置,当然你可以在这个for循环中就把 i
第一次循环看成他的值为 0
如果 i 第一次循环为 0
,i
又 小于 10,i
每次循环 ++ (i+1)
那么 Console.WriteLine(i.ToString());
打印出的代码就是 0,1,2,3,4,5,6,7,8,9
, 每次循环只打印一个数, 你可以把 i
看成 当前循环对象中的每一项
异常处理
using System; namespace ConsoleApp1 { class Program { static void Main(string[] args) { // 测试异常 Console.WriteLine("请输入你的年龄:"); string str = Console.ReadLine(); try { int age = int.Parse(str) + 10; Console.WriteLine("十年后的年龄是:" + age.ToString()); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } Console.ReadKey(); } } }
try catch
是众多语言中用到的一种处理异常的方式,其中try
代码块中会执行
面向对象
经典的面向对象,是一种常见的编程范式,把现实生活中的事物抽象成程序中的类,每个类都有属于自己的属性和方法,进行一些数据处理
类和对象
举例说明
using System; namespace cs_day02_04 { class Program { static void Main(string[] args) { // 面向对象 Hero hr = new Hero(); Console.WriteLine("你是?"); hr.name = Console.ReadLine(); Console.WriteLine("你好我是" + hr.name); Console.WriteLine("你多大?"); string age = Console.ReadLine(); hr.age = int.Parse(age); Console.WriteLine("你好我" + hr.age + "岁"); Console.ReadKey(); } } class Hero { public string name; public int age; // 还可以定义方法 //public void Hello() //{ // Console.WriteLine("hello~"); //} } }
上面我们实现了 类
的 定义
以及 实例化
类后调用类的属性或方法.
定义类
// 修饰符 class 类名 { // 属性或方法... //}
首先,我们定义了一个叫做 Hero
的类, 并在主入口程序 Main
中进行了对 Hero
类的实例化
Hero hr = new Hero(); // 类的实例化
其中 hr
包含此类中的所有属性和方法,比如说我们要访问类中的 name
,就可以使用 hr.name
来获取此属性的值,这是根据修饰符来决定的,如果修饰符不为 public
而是 private
想要获取某些属性我们必须使用类中的 get
方法,类属性的 get
set
方法会在下方几条内容后详细介绍
static 关键字
static 系统性介绍
在面向对象的编程中,“static”
(静态)是一个关键字,用于定义类级别的成员(属性和方法),而不是对象级别的。
下面是一些关于 "static"
的重要概念和用法:
静态成员(Static Members):
静态成员是属于类本身的,而不是类的实例。这意味着所有类的实例都共享相同的静态成员。
静态成员可以是静态属性(静态变量)或静态方法。它们不依赖于对象的创建,可以直接通过类名来访问。
静态属性(Static Properties):
静态属性是属于类的属性,而不是实例的属性。它们在所有类的实例之间共享相同的值。
静态属性可以用于存储类级别的常量、全局配置和共享状态等信息。
静态方法(Static Methods):
静态方法是属于类的方法,而不是实例的方法。它们直接通过类名调用,无需实例化对象。
静态方法通常用于执行与类相关的功能,例如工具函数、辅助方法或全局操作。
使用静态成员的优势:
共享数据:静态成员可以用于共享数据,避免每个对象都拥有自己的副本。
简化访问:静态成员可以通过类名直接访问,不需要创建对象实例。
提高性能:访问静态成员速度更快,因为它们不需要通过对象的引用来访问。
然而,使用静态成员也有一些限制和注意事项:
静态成员无法访问实例成员,因为它们不存在于特定对象的上下文中。
静态成员无法被继承,子类只能通过类名访问静态成员。
静态成员的使用应该谨慎,因为它们破坏了对象的封装性和可测试性。
// 不用static关键字声明的变量或方法: public string name; // 调用: Class name = new Class(); Console.WriteLine(name.name); ---------------------------------------------------- // 使用static关键字声明的变量或方法: public static string name; // 调用: Console.WriteLine(Class.name);
代码抽离问题
如果不想代码界面过于臃肿,可以采用创建类文件的形式,把某些类放到创建的cs文件中,这样主程序类既可以调用此类,代码也会非常清晰,编码体验会得到显著的提升
- 右键项目文件,选择添加,类,就可以创建自己的cs文件
创建一个Student
类, 里面放上这样一段代码
using System; namespace MyCode { public class Student // 请记住这个 public 修饰符 { public string name = "zhangsan"; public int age = 12; public void Say() { Console.WriteLine(name + age + "岁"); } } }
然后我们在 Program.cs
内使用它
using System; namespace cs_day_03 { class Program { static void Main(string[] args) { // 代码抽离 Student student = new Student(); // 和写在 Program.cs 内作用一样,可以直接拿来进行实例化 student.Say(); // 调用类中的方法 Console.ReadKey(); } } }
在程序文件中引入dll扩展
我们右键解决方案,移动到添加,新建项目,新建一个
类库(NET Framework)
项目,这是一个可以生成dll
文件供控制台项目使用的我们自己写的类库,项目名暂定为MyCode
把 Class1.cs
删除,添加一个名为 Student
的 cs文件
文件内放和上方同样的代码
using System; namespace MyCode { // class Student 默认为 private class Student // 必须是public 别的项目引用dll,才能访问这个类 public class Student { public string name = "zhangsan"; public int age = 12; public void Say() { Console.WriteLine(name + age + "岁"); } } }
右键 MyCode
项目文件,点击 重新生成
,此时代码会 重新编译
然后我们在需要引用 MyCode dll文件
的地方添加引用
天机成功后,展开引用,会有一个MyCode的dll控制台扩展文件
我们在需要引入dll
文件的项目中 使用 using MyCode;
引入扩展文件
using MyCode; // 重新生成后标红线就会有提示using了 using System; // using MyCode; 找不到, 只会在当前目录尝试找,不会在隔壁目录找 // MyCode 会生成dll文件,把dll文件引用: 添加引用,浏览找到要引用的dll文件 namespace cs_day_03 { class Program { static void Main(string[] args) { // 代码抽离 Student student = new Student(); student.Say(); Console.ReadKey(); } } }
如果你和上面代码相同,using MyCode;
还是标红,请右键 MyCode
文件 点击 重新生成
关于生成文件类型
右键文件,点击属性,可以在输出类型中修改文件类型,exe, dll…
控制台项目操作文件小项目
using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace ChangeFile { class Program { static void Main(string[] args) { // 定义路径 string path = "C:/Users/ASUS/Desktop"; // 获取目录下所有文件的路径 DirectoryInfo root = new DirectoryInfo(path); FileInfo[] files = root.GetFiles(); // 泛型集合 存储的都是 类型为FileInfo的集合 List<FileInfo> lstFiles = files.ToList(); // 循环文件 foreach (var item in lstFiles) { if (item.Name == "123.txt") { System.IO.File.Delete(item.FullName); Console.WriteLine("删除成功,删除文件:" + item); } else { Console.WriteLine("未找到:123.txt"); } } // 监听键盘 Console.ReadKey(); } }
DirectoryInfo
是一个类,用于表示文件夹的信息和操作。
root
是一个DirectoryInfo
类型的变量,它用于表示指定路径path
对应的文件夹。
path
是一个字符串,表示文件夹的路径。
GetFiles()
是DirectoryInfo
类的方法,用于获取文件夹中的文件。
files
是一个FileInfo
类型的数组,它包含了文件夹中的所有文件信息。
ToList()
是IEnumerable<T>
接口的扩展方法,用于将数组转换为列表.
lstFiles
是一个List<FileInfo>
类型的变量,它包含了由files
数组转换而来的文件信息列表。
内容解释
我们首先定义了一个 path,指向桌面的路径 获取了该 path 路径下所有的文件夹 然后我们使用了 GetFiles() 获取了文件夹下的所有文件 使用 List 集合接收FileInfo类型的数据,使用ToList()将数组转换为列表 接下来我们使用 foreach 循环了lstFiles,若lstFiles内如果有一项的名称(带后缀)为 123.txt,则我们调用 System.IO.File.Delete 方法进行删除操作 若没有名为 123.txt 的文件,则打印 "未找到:123.txt" 最后我们监听用户的键盘按下,关闭cmd终端
文件操作微优化
using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace ChangeFile { class Program { static void Main(string[] args) { // 定义路径 Console.WriteLine("请输入你要寻找的路径: "); string path = Console.ReadLine(); if (Directory.Exists(path)) { // 获取目录下所有文件的路径 DirectoryInfo root = new DirectoryInfo(path); FileInfo[] files = root.GetFiles(); // 存储类型为FileInfo的集合 List<FileInfo> lstFiles = files.ToList(); // 循环文件 foreach (var item in lstFiles) { // 定义一个变量接收 string fileName = item.Name; // 进行判断 if (fileName == "123.txt") { System.IO.File.Delete(item.FullName); Console.WriteLine("删除成功,删除文件:" + item); Console.ReadKey(); } else { Console.WriteLine("未找到:123.txt"); } bool isHave = fileName.Contains("456"); if (isHave) { // 如果包含的话,给文件改个名字 string srcFileName = item.FullName; // 定义当前文件的路径 string destFileName = item.Directory.FullName + "/changeFileName" + item.Extension; // 替换的名字 File.Move(srcFileName, destFileName); // 两个参数,一个是源文件参数,一个是目标文件参数 } } } else { Console.WriteLine("系统并未找到相关路径, 请检查路径是否输入正确!"); } // 监听键盘 Console.ReadKey(); } }
扩展代码请在
bool isHave = fileName.Contains("456");
后开始观看
扩展代码所用到的方法:
方法 / 字段 | 解释 |
方法 :Contains() | 字符串方法Contains() 检测一个字符串内是否包含给定的字符串 |
方法 :File.Move(param1, param2) | File.Move(param1, param2) 接收两个方法,第一个参数为源文件参数,第二个参数为目标文件参数,用来修改文件名 |
[扩展,并未用到] 方法:Replace() | Replace() 方法是替换某一个字符串内的特定内容 |
字段:item.FullName | 当前文件的绝对路径 |
字段:item.Directory.FullName | 返回当前文件所在目录的路径 |
字段:item.Extension | 当前文件的后缀文件类型 |
这段代码我们检测了如果某一项文件名称包含
"456"
,则把这个文件改名为文件所在的项目目录/changeFileName.文件后缀名
扩展教学
单讲 类属性的
Get Set
方法
若有这样一个类
using System; namespace Demo { class DemoClass { private string name = "张三"; private int age = 18; } }
因为
private
是私有属性,是不可以由实例化来获取的,那我们应该怎么获取由私有属性修饰符标注的变量呢?
定义一个 get
方法
using System; namespace Demo { class DemoClass { private string name = "张三"; private int age = 18; // 定义一个 get 方法,可以获取指定的属性 public void GetName() { return name; } } }
然后我们可以在别的文件中,实例化类之后调用 DemoClass
的 GetName()
方法, 返回值为 "张三"
using System; namespace hahha { class Program { DemoClass demo = new DemoClass(); // 进行类的实例化 Console.WriteLine(demo.GetName()); // 打印demo类的GetName()方法,控制台打印出: "张三" Console.ReadKey(); // 监听键盘 } }
定义一个 set
方法,修改类属性
using System; namespace Demo { class DemoClass { private string name = "张三"; private int age = 18; // 定义一个 get 方法,可以获取指定的属性 public String SetName(string name) { // 标注类型 this.name = name; // 赋值操作 } } }
调用 SetName(param)
方法
using System; namespace hahha { class Program { DemoClass demo = new DemoClass(); // 进行类的实例化 demo.SetName("李四"); // 修改 name 为 "李四" Console.WriteLine(demo.GetName()); // 打印出 "李四" Console.ReadKey(); // 监听键盘 } }
完结撒花 🌸
完结撒花!此套课程仅为理解,基础不全,了解更多还要继续学习