【C# 控制台】主要讲述以下C#的部分语法,部分基础,做到了解作用

在这里插入图片描述

博主:_LJaXi Or 東方幻想郷
专栏: C#开发 | 控制台/.NET/.NET Core
开发工具:Visual Studio


emm…还是看看吧,就是一个小控制台案例,里面的语法都会解释下,此博客只是兴趣观看,远远达不到标准教学作用,可以用来熟悉c#语法
Java基础今年必更完…

C# 控制台程序

  • 创建项目流程
  • 项目文件介绍
  • C# 的代码结构
  • 变量类型介绍
  • 简单的语法介绍
    • 打印内容
    • 控制台输入
  • 输入操作进行数据处理
  • 方法
  • 循环
  • 异常处理
  • 面向对象
    • 类和对象
    • static 关键字
  • 代码抽离问题
  • 在程序文件中引入dll扩展
  • 关于生成文件类型
  • 控制台项目操作文件小项目
    • 内容解释
  • 文件操作微优化
  • 扩展教学
  • 完结撒花

创建项目流程

  1. 项目模板选择 ----- 控制台应用(NET Framework)
  2. 创建项目流程
  3. 项目名称可以先选择默认,选择好NET框架版本后直接点击创建项目
    【C# 控制台】主要讲述以下C#的部分语法,部分基础,做到了解作用_第1张图片

不出意外的话,点击创建项目,我们的Vs Studio就会打开项目


项目文件介绍

首先映入眼帘的应该是vs studio开发界面,此时往右看你会看到项目的展开列表
我们只需要关心 Program.cs 这是执行类文件,点击vs studio顶部的启动,运行的就是Program.cs文件内容
【C# 控制台】主要讲述以下C#的部分语法,部分基础,做到了解作用_第2张图片

注意: cs文件就是 Csharp文件

点击启动:
【C# 控制台】主要讲述以下C#的部分语法,部分基础,做到了解作用_第3张图片
当然这是我写了一部分内容,终端才会输出一些东西,你看到的应该是全黑,闪一下就会退出


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,按下任意一个键退出终端,如果不加上这个,程序闪一下就会自动退出
        }
    }
}

然后点击启动,你会看到这样的画面…
【C# 控制台】主要讲述以下C#的部分语法,部分基础,做到了解作用_第4张图片
看!打印出了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多岁的老同志,这个 ifelse 是个什么东西啊?
诶!我大意了,没闪,接下来先给大家介绍一下 if elsec# 中的作用

int a = 1;

// if 在众多开发语言内都是判断语句是否达到标准,从而执行一套执行标准或执行不标准判断的一种表现形式
if(a == 1) { // 如果...
	// 执行代码区
	Console.WriteLine("我是1");
} else { // 不然...
	// 执行代码区
	Console.WriteLine("我不是1");
}

if(判断条件) { // 如果...
	// 执行代码区
} else { // 不然...
	// 执行代码区
}

咳咳,好了我们说回正题

  1. 关于上面那个小案例,我们首先在控制台输出了一些辅助性的文字,让用户输入 姓名 故乡 爱好
  2. 然后使用了 变量类型 变量名称 = Console.ReadLine(); 来接收输入的内容
  3. 然后我们使用了 if else 分别判断了name输入的是否是 "张三" 如果是则执行if内的代码,不是则执行else内的代码,然后我们修改了 address hobby 的值
  4. 最后我们输出了用户输入的 故乡 爱好

点击启动,在输入姓名 故乡 爱好 之后,它看起来是这样的
【C# 控制台】主要讲述以下C#的部分语法,部分基础,做到了解作用_第5张图片
如果这个案例也成功,那恭喜你,这可真是泰裤辣!

输入操作进行数据处理

经过前面的练习,应该已经对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)
【C# 控制台】主要讲述以下C#的部分语法,部分基础,做到了解作用_第6张图片
通过源码可以看到 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 第一次循环为 0i 又 小于 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文件中,这样主程序类既可以调用此类,代码也会非常清晰,编码体验会得到显著的提升

  1. 右键项目文件,选择添加,类,就可以创建自己的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文件

【C# 控制台】主要讲述以下C#的部分语法,部分基础,做到了解作用_第7张图片

文件内放和上方同样的代码

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文件 的地方添加引用

【C# 控制台】主要讲述以下C#的部分语法,部分基础,做到了解作用_第8张图片
天机成功后,展开引用,会有一个MyCode的dll控制台扩展文件
【C# 控制台】主要讲述以下C#的部分语法,部分基础,做到了解作用_第9张图片
我们在需要引入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…
【C# 控制台】主要讲述以下C#的部分语法,部分基础,做到了解作用_第10张图片

控制台项目操作文件小项目

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 接口的扩展方法,用于将数组转换为列表.
lstFiles 是一个 List 类型的变量,它包含了由 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;
		}
    }
}

然后我们可以在别的文件中,实例化类之后调用 DemoClassGetName() 方法, 返回值为 "张三"

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(); // 监听键盘
    }
}

完结撒花

完结撒花!此套课程仅为理解,基础不全,了解更多还要继续学习

你可能感兴趣的:(C#开发,控制台/.NET/.NET,Core,c#,开发语言,.NET)