在C++基础上理解CSharp-1

我们接下来的全部环境都是在VS2022上,前置的环境配置只需要选择C#环境开发就行了

1:C#语言介绍

C#(读作 "C Sharp")是由微软公司在 2000 年发布的一种现代、通用、类型安全、面向对象的编程语言,由传奇程序员 Anders Hejlsberg(Delphi、Turbo Pascal、TypeScript 的主要设计者)亲自领导设计。C# 从诞生之初就定位为.NET 平台的核心语言,经过 20 多年的发展,已经成为世界上最流行的编程语言之一。

1:C#语言发展历史与版本演进

C# 的发展与.NET 平台的发展紧密相连,每个主要版本都带来了革命性的语法特性:

  • C# 1.0(2002 年):基础版本,包含类、继承、接口、委托、事件等核心面向对象特性
  • C# 2.0(2005 年):泛型、匿名方法、迭代器、可空类型
  • C# 3.0(2007 年):LINQ、Lambda 表达式、扩展方法、自动属性、匿名类型
  • C# 4.0(2010 年):动态类型、命名参数、可选参数、协变与逆变
  • C# 5.0(2012 年):async/await 异步编程模型(C# 最重要的特性之一)
  • C# 6.0(2015 年):字符串插值、空条件运算符、自动属性初始化器
  • C# 7.0-7.3(2017-2018 年):元组、模式匹配、本地函数、ref 返回
  • C# 8.0(2019 年):可空引用类型、异步流、接口默认方法、范围和索引
  • C# 9.0(2020 年):顶级语句、记录类型、init-only 属性、模式匹配增强
  • C# 10.0(2021 年):全局 using 指令、文件范围命名空间、结构改进
  • C# 11.0(2022 年):原始字符串、必需成员、泛型数学、UTF-8 字符串字面量
  • C# 12.0(2023 年):主构造函数、集合表达式、默认 lambda 参数、内联数组

2:C#与C++的对比

对比维度 C# C++
执行模型 托管执行,运行在 CLR 上,自动内存管理 原生执行,直接编译为机器码,手动内存管理
类型系统 强类型、类型安全,所有类型最终继承自 object 强类型,但存在类型不安全的操作(如指针强制转换)
内存管理 垃圾回收 (GC) 自动回收不再使用的内存,无需手动 delete 开发者手动分配 (new) 和释放 (delete) 内存,容易出现内存泄漏和野指针
指针使用 默认禁止指针,仅在 unsafe 代码块中允许使用 指针是核心特性,可以自由操作内存地址
编译过程 两步编译:C# 代码 → IL 中间语言 → JIT 编译为机器码 一步编译:C++ 代码 → 机器码
标准库 极其丰富的基础类库 (BCL),涵盖几乎所有常见开发需求 标准库相对较小,很多功能需要依赖第三方库
开发效率 极高,大量语法糖和工具支持 较低,需要处理很多底层细节
运行性能 接近原生,JIT 编译器可以进行运行时优化 最高,编译时可以进行深度优化
跨平台能力 现代.NET (.NET 5+) 支持 Windows、Linux、macOS、Android、iOS 等所有主流平台 原生跨平台,但需要为每个平台单独编译
错误处理 统一的异常处理机制 异常处理可选,很多 C++ 代码仍然使用返回值处理错误

3:C#的核心程序理念

  • 生产力第一:C# 的首要设计目标是提高开发者的生产力,通过语法糖、类型推断、自动内存管理等特性减少开发者的重复劳动
  • 类型安全:C# 在编译时和运行时都进行严格的类型检查,防止类型错误
  • 面向对象:C# 是纯面向对象语言,所有代码都必须写在类中(除了顶级语句)
  • 组件导向:C# 从设计之初就支持组件开发,提供了属性、事件、委托等组件级别的特性
  • 向后兼容:微软对 C# 的向后兼容性非常重视,旧代码几乎不需要修改就能在新版本的.NET 上运行

2:C#的应用领域

1:游戏开发

C# 是Unity 游戏引擎的官方编程语言,而 Unity 占据了全球移动游戏市场 60% 以上的份额,以及 PC 和主机游戏市场的很大一部分。使用 C# 开发的知名游戏包括:

  • 《王者荣耀》
  • 《原神》
  • 《崩坏:星穹铁道》
  • 《Among Us》
  • 《Hollow Knight》
  • 《Pokémon Go》

除了 Unity,C# 还可以用于 Godot 引擎和 Unreal Engine 的脚本开发。

2:桌面应用开发

  • WPF(Windows Presentation Foundation):微软推出的现代化桌面开发框架,支持 XAML 标记语言、数据绑定、动画、3D 图形等高级特性,是开发 Windows 桌面应用的首选
  • WinForms:传统的 Windows 窗体开发框架,简单易用,适合快速开发简单的桌面应用
  • MAUI(Multi-platform App UI):微软最新的跨平台 UI 框架,一套代码可以同时运行在 Windows、macOS、Android 和 iOS 上
  • Avalonia UI:开源的跨平台 UI 框架,支持更多平台,包括 Linux 和 WebAssembly

3:Web应用开发

ASP.NET Core 是微软推出的跨平台 Web 开发框架,是目前性能最高的 Web 框架之一。ASP.NET Core 支持:

  • MVC (Model-View-Controller) 模式
  • Web API 开发
  • Razor Pages 页面开发
  • Blazor WebAssembly(使用 C# 开发前端应用)
  • SignalR 实时通信

使用ASP.NET Core 开发的知名网站包括:

  • Stack Overflow
  • Microsoft 官网
  • GitHub 的部分服务
  • 国内很多大型企业的后台系统

4:移动应用开发

  • MAUI:微软官方的跨平台移动开发框架,替代了之前的 Xamarin
  • Xamarin:成熟的跨平台移动开发框架,可以使用 C# 开发原生 Android 和 iOS 应用
  • Unity:如前所述,也可以用于开发移动游戏和应用

5:云服务与后台开发

C# 是微软 Azure 云平台的首选语言,同时也可以很好地运行在 AWS、Google Cloud 等其他云平台上。C# 适合开发:

  • 微服务
  • 云函数
  • 后端 API
  • 消息队列处理
  • 大数据处理

6:其他领域

  • 物联网 (IoT):.NET IoT 库支持在 Raspberry Pi 等设备上运行 C# 代码
  • 人工智能与机器学习ML.NET是微软推出的.NET 机器学习框架
  • 桌面自动化:可以使用 C# 开发自动化脚本,控制其他应用程序
  • 数据库开发:可以使用 C# 开发 SQL Server 的存储过程和函数

3:.NET平台解析

C# 不能脱离.NET 平台运行,.NET 是一个完整的软件开发平台,包含了运行时、编译器、类库和工具链。

1:.NET平台演变

2:.NET平台的核心组件

一个完整的.NET 应用程序的运行依赖于以下几个核心组件:

1:CLR (Common Language Runtime) 公共语言运行时

CLR 是.NET 平台的核心,负责管理程序的执行,提供以下核心服务:

  • 垃圾回收 (Garbage Collection):自动检测并回收不再被引用的对象所占用的内存,彻底解决了 C++ 中常见的内存泄漏问题
  • 类型安全检查:在编译时和运行时验证类型的正确性,防止非法的类型转换和内存访问
  • 异常处理:提供统一的异常处理机制
  • JIT (Just-In-Time) 即时编译:将 IL 中间语言编译为当前平台的机器码
  • 代码访问安全 (CAS):控制代码的访问权限
  • 线程管理:管理应用程序中的线程
2:BCL (Base Class Library) 基础类库

BCL 是.NET 平台提供的标准类库,包含了数千个预定义的类和方法,涵盖了几乎所有常见的开发需求:

  • 基本数据类型(int、string、bool 等)
  • 集合类(List、Dictionary、Queue、Stack 等)
  • 字符串处理
  • 文件 IO 和流操作
  • 网络通信
  • 日期和时间处理
  • 数学计算
  • 加密和解密
  • 反射
  • 序列化
  • 多线程和异步编程
3:编译器

.NET 平台为不同的语言提供了各自的编译器:

  • Roslyn:C# 和 Visual Basic 的编译器,本身也是用 C# 编写的,提供了丰富的代码分析和生成 API
  • F# 编译器:用于编译 F# 语言
  • IL 编译器:将 IL 中间语言编译为机器码
4:工具链

.NET 平台提供了完整的开发工具链:

  • Visual Studio 2022:功能最强大的 IDE,提供了代码编辑、调试、测试、部署等一站式服务
  • .NET CLI:跨平台的命令行工具,可以在任何操作系统上创建、构建、运行和发布.NET 应用
  • NuGet:.NET 的包管理器,包含了数百万个第三方库

3:.NET程序的编译与执行过程

C# 程序的执行过程与 C++ 有很大的不同,分为两个阶段:

  1. 编译阶段 :C# 编译器 (csc.exe) 将 C# 源代码编译为IL (Intermediate Language) 中间语言,同时生成元数据 (Metadata)。IL 是一种与平台无关的低级语言,类似于汇编语言。

  2. 运行阶段 :当用户运行程序时,CLR 的 JIT 编译器将 IL 中间语言即时编译为当前 CPU 架构的机器码。JIT 编译器可以进行运行时优化,例如根据当前 CPU 的特性生成优化的代码,或者根据程序的运行情况进行热点优化。

这种编译方式结合了解释型语言和编译型语言的优点:

  • 跨平台:一次编译,到处运行
  • 高性能:JIT 编译生成的机器码性能接近原生代码
  • 运行时优化:可以进行静态编译器无法进行的优化

4:第一个C#项目

我们已经在 VS2022 中创建了一个传统风格的 C# 控制台应用项目,项目名称为CppToCSharp.Basics。现在我们来详细解析这个项目的每一个部分。

1:项目结构

复制代码
解决方案 'CppToCSharp.Basics' (1个项目)
└── CppToCSharp.Basics
    ├── 依赖项
    │   ├── 框架
    │   │   └── Microsoft.NETCore.App
    │   └── 包
    ├── Properties
    │   └── launchSettings.json
    └── Program.cs
1:解决方案文件(.sln)

解决方案文件是一个文本文件,包含了一个或多个项目的信息,以及它们之间的依赖关系。VS2022 通过解决方案文件来管理多个项目。

2:项目文件(.csproj)

项目文件是一个 XML 文件,包含了项目的所有配置信息:

  • 目标框架(例如 net8.0)
  • 输出类型(控制台应用、类库、Web 应用等)
  • 引用的程序集和 NuGet 包
  • 编译选项
  • 项目中包含的文件
3:Properties文件夹

Properties 文件夹包含项目的属性文件,其中最重要的是launchSettings.json,它包含了项目的调试配置,例如:

  • 启动时的命令行参数
  • 工作目录
  • 环境变量
  • 要使用的浏览器(对于 Web 应用)
4:项目项依赖文件夹

依赖项文件夹显示了项目引用的所有依赖项,包括:

  • 框架依赖:.NET 基础类库
  • NuGet 包:第三方库
  • 项目引用:同一解决方案中的其他项目
5:Program.cs文件

Program.cs 是主程序文件,包含了程序的入口点。我们当前的代码是:

cs 复制代码
namespace CppToCSharp.Basics
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
        }
    }
}

这是传统的 C# 控制台应用程序结构,我们来逐行详细解释:

  1. namespace CppToCSharp.Basics

    • 定义了一个命名空间,命名空间用于组织代码,避免命名冲突
    • 类似于 C++ 的namespace关键字
    • 命名空间可以嵌套,使用点号分隔
    • 按照约定,命名空间使用公司名称。项目名称的格式
  2. internal class Program

    • 定义了一个名为Program的类
    • internal是访问修饰符,表示这个类只能在当前程序集中访问
    • C# 是纯面向对象语言,所有代码都必须写在类中
    • 类名通常使用 PascalCase 命名法(首字母大写)
  3. static void Main(string[] args)

    • 这是程序的入口点方法,每个 C# 应用程序必须有且只有一个入口点
    • static表示这个方法属于类本身,而不是类的实例
    • void表示这个方法没有返回值
    • Main是入口点方法的固定名称,大小写敏感
    • string[] args是命令行参数数组,类似于 C++ 的char* argv[]
  4. Console.WriteLine("Hello, World!");

    • 调用System.Console类的WriteLine方法,向控制台输出一行文本
    • Console类位于System命名空间中
    • 类似于 C++ 的std::cout << "Hello, World!" << std::endl;

2:运行程序

点击 VS2022 工具栏中的绿色 "启动调试" 按钮,或者按 F5 键,程序会编译并运行。你会看到一个控制台窗口弹出,显示 "Hello, World!",然后窗口会立即关闭。

为了让窗口保持打开状态,你可以在代码末尾添加一行Console.ReadKey();

Console.ReadKey()方法会等待用户输入一个字符,然后返回。这样你就有足够的时间看到程序的输出。

5:C#的基础语法入门

1:注释

C#的注释和C++完全一样

2:变量声明和初始化

C# 的变量声明语法与 C++ 类似,但有一些重要区别:

cs 复制代码
// 显式类型声明
int age = 25;
string name = "张三";
double height = 1.75;
bool isStudent = true;
char gender = 'M';

// 隐式类型声明(var关键字)
var score = 95.5; // 编译器自动推断为double类型
var message = "Hello C#"; // 编译器自动推断为string类型
var numbers = new int[] { 1, 2, 3, 4, 5 }; // 编译器自动推断为int[]类型

注意:

  • C# 中的变量必须先声明后使用
  • C# 不允许使用未初始化的变量,这一点比 C++ 更严格
  • var关键字只是语法糖,变量仍然是强类型的,编译时类型就确定了
  • 变量名通常使用 camelCase 命名法(首字母小写,后续单词首字母大写)

3:控制台输入输出

C# 提供了Console类来处理控制台输入输出:

cs 复制代码
// 输出
Console.WriteLine("这是一行文本,输出后自动换行");
Console.Write("这是一行文本,输出后不换行");

// 输入
Console.WriteLine("请输入你的名字:");
string userName = Console.ReadLine(); // 读取一行输入,返回字符串

Console.WriteLine("请输入你的年龄:");
string ageInput = Console.ReadLine();
int userAge = int.Parse(ageInput); // 将字符串转换为整数

// 字符串插值(C# 6.0+)
Console.WriteLine($"你好,{userName},你今年{userAge}岁了");

4:算术运算符

C# 的算术运算符与 C++ 完全相同:

cs 复制代码
int a = 10;
int b = 3;

int sum = a + b; // 13
int difference = a - b; // 7
int product = a * b; // 30
int quotient = a / b; // 3(整数除法,与C++相同)
int remainder = a % b; // 1(取余)

a++; // 自增
b--; // 自减

a += 5; // 等价于 a = a + 5;
b *= 2; // 等价于 b = b * 2;

6:简单计算器(C#)

cs 复制代码
namespace CppToCSharp.Basics
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("简单计算器");
            Console.WriteLine("----------");
            Console.WriteLine("请输入第一个数字");
            double num1 = double.Parse(Console.ReadLine());

            Console.WriteLine("请输入第二个数字");
            double num2= double.Parse(Console.ReadLine());
            Console.WriteLine("请选择运算");
            Console.WriteLine("1. 加法");
            Console.WriteLine("2. 减法");
            Console.WriteLine("3. 乘法");
            Console.WriteLine("4. 除法");
            Console.Write("请输入选项(1-4):");

            int choice = int.Parse(Console.ReadLine());

            double result = 0.0;
            switch (choice)
            {
                case 1:
                    result = num1 + num2;
                    Console.WriteLine($"{num1}+{num2}={result}");
                    break;
                case 2:
                    result = num1 - num1;
                    Console.WriteLine($"{num1}-{num2}={result}");
                    break;
                case 3:
                    result = num1 * num2;
                    Console.WriteLine($"{num1} * {num2} = {result}");
                    break;
                case 4:
                    if (num2 == 0)
                    {
                        Console.WriteLine("错误:除数不能为零");
                    }
                    else
                    {
                        result = num1 / num2;
                        Console.WriteLine($"{num1} / {num2} = {result}");
                    }
                    break;
                default:
                    Console.WriteLine("无效选项");
                    break;
            }
        }
    }
}

下一篇博客我们将创建一个名为CSharpDataTypes的新项目,深入学习 C# 的数据类型系统,重点讲解 C# 特有的值类型与引用类型的区别,这是理解 C# 的关键。我们还会详细介绍 C# 的所有基本数据类型、变量与常量、以及类型转换机制。

相关推荐
一念春风1 小时前
QwenPaw(替代小龙虾)大模型
开发语言·php
小短腿的代码世界1 小时前
Qt状态机框架深度解析:从状态图到事件驱动闭环
开发语言·qt
学习,学习,在学习1 小时前
Q工控仪器程序框架设计详解(工控)
c++·qt·架构·qt5
j7~1 小时前
【Linux系统】基础IO(文件描述)(1)
linux·服务器·c++·文件·基础io
广州灵眸科技有限公司1 小时前
瑞芯微(EASY EAI)RV1126B 模型部署API说明
linux·开发语言·网络·人工智能·深度学习·算法·yolo
计算机安禾1 小时前
【c++面向对象编程】第20篇:override与final关键字:现代C++对继承的控制
开发语言·c++
AI科技星1 小时前
全域数学:从理论到现实的终极落地全记录 光速不变公理(v=c)+ 可见派维度常数公理(D_v=3)统一广义相对论与量子力学,解决物理学百年难题
c语言·开发语言
ch.ju1 小时前
Java程序设计(第3版)第三章——数组的定义方式
java·开发语言
郝学胜-神的一滴1 小时前
Qt 高级开发 004: 三大窗口类深度解析
开发语言·c++·qt·程序人生·系统架构