C#语法基础

一、什么是.NET平台

.NET 是由 Microsoft 支持的免费开放源代码应用程序平台。

.NET

  • .NET 是一个安全、可靠且高性能的应用程序平台。
  • C# 是 .NET 的编程语言。它是强类型且类型安全的,并集成了并发和自动内存管理。

C#

  • C# 是一种新式、安全且面向对象的编程语言,既有面向数据的记录等高级功能,也有函数指针等低级功能。

跨平台

  • Android、Apple、Linux 和 Windows 操作系统均支持 .NET。它在多个 Linux 发行版(如 Red Hat Enterprise Linux 和 Ubuntu)中提供。

  • .NET 包括一组标准库和 API,涵盖集合、网络到机器学习。
  • NuGet 是 .NET 的包管理器,包含超过 300000 个包。

应用

工具

  • 可以在任何操作系统上使用 .NET CLI、Visual Studio、Visual Studio Code 和其他工具生成应用。配置与GitHub Actions 等服务的持续集成并将部署推送到云的操作非常简单。

二、搭建C#开发环境

安装SDK

https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/sdk-9.0.300-windows-x64-installer

安装Visual Studio2022

https://visualstudio.microsoft.com/zh-hans/vs/

三、C#基础

C#程序示例及程序结构解释


📄控制台应用程序

csharp 复制代码
// 引入命名空间:System 包含基本类,如 Console、String 等
using System;

// 定义一个命名空间,用于组织代码,避免类名冲突
namespace MyFirstApp
{
    // 定义一个类,C# 中所有代码必须写在类中
    class Program
    {
        // 主函数:程序入口点
        // args 表示命令行参数(可选)
        static void Main(string[] args)
        {
            // 输出欢迎信息到控制台
            Console.WriteLine("欢迎使用 C# 示例程序!");

            // 调用自定义方法
            GreetUser();

            // 提示用户输入姓名
            Console.Write("请输入你的名字:");
            string name = Console.ReadLine();  // 读取用户输入

            // 使用字符串插值输出问候语
            Console.WriteLine($"你好, {name}!欢迎来到 C# 世界。");

            // 显示程序结束提示
            Console.WriteLine("程序即将结束,请按任意键退出...");
            Console.ReadKey();  // 阻塞程序直到用户按键
        }

        // 自定义方法:向用户打招呼
        static void GreetUser()
        {
            Console.WriteLine("很高兴见到你!");
        }
    }
}

🧩 模板结构说明

部分 说明
using System; 引入系统命名空间,提供常用类支持
namespace MyFirstApp 将代码封装进一个逻辑组中,方便管理和维护
class Program 定义一个类,包含程序逻辑
static void Main(string[] args) 程序入口方法,程序从这里开始执行
Console.WriteLine() 向控制台输出一行文本并换行
Console.Read() / ReadLine() 从控制台读取用户输入
GreetUser() 自定义静态方法,用于模块化代码
Console.ReadKey() 防止控制台窗口一闪而过,等待用户按键

▶️ 运行效果(模拟)

复制代码
欢迎使用 C# 示例程序!
很高兴见到你!
请输入你的名字:李四
你好, 李四!欢迎来到 C# 世界。
程序即将结束,请按任意键退出...

📌 小贴士

  • 可以将这个模板保存为 .cs 文件(如 Program.cs),然后使用 Visual Studio 或 .NET CLI 编译运行。

  • 若使用 .NET CLI:

    bash 复制代码
    dotnet new console -n MyFirstApp
    cd MyFirstApp
    dotnet run

C#控制台读取值


✅示例:读取姓名和年龄,并输出信息

csharp 复制代码
using System;

class Program
{
    static void Main()
    {
        // 读取姓名
        Console.Write("请输入你的名字:");
        string name = Console.ReadLine();

        // 读取年龄并转换为整数
        Console.Write("请输入你的年龄:");
        int age = int.Parse(Console.ReadLine());

        // 输出结果
        Console.WriteLine($"你好,{name}!你今年 {age} 岁。");

        // 等待按键退出
        Console.WriteLine("按任意键退出...");
        Console.ReadKey();
    }
}

📝 注释说明(逐行解释)

代码 注释
using System; 引入系统命名空间,使用基础类库
class Program 定义一个类,C# 所有代码都写在类中
static void Main() 程序入口点
Console.Write(...); string name = ... 提示并读取用户输入的名字
Console.Write(...); int age = ... 提示并读取年龄,使用 int.Parse 转换为整数
Console.WriteLine(...) 使用字符串插值输出信息
Console.ReadKey() 防止控制台窗口关闭,等待用户按键

⚠️ 注意事项(补充)

  • int.Parse():如果输入不是合法整数,程序会崩溃。
  • 推荐使用 int.TryParse() 来进行安全转换(适用于更健壮的程序)。

C#命令行参数


🧩什么是命令行参数?

当你运行一个控制台程序时,可以在启动命令后面加上一些额外的信息(称为参数),例如:

bash 复制代码
MyApp.exe 参数1 参数2 参数3

这些参数可以通过 Main 方法的参数 string[] args 来获取和处理。


✅ 代码示例

csharp 复制代码
using System;

class Program
{
    static void Main(string[] args)
    {
        // 检查是否有参数传入
        if (args.Length == 0)
        {
            Console.WriteLine("未提供任何命令行参数。");
            return;
        }

        // 输出所有参数
        Console.WriteLine("你输入的命令行参数为:");

        for (int i = 0; i < args.Length; i++)
        {
            Console.WriteLine($"参数 {i}:{args[i]}");
        }
    }
}

📝 注释说明

行号 代码 注释
1 using System; 引入系统命名空间,用于控制台输入输出
3 class Program 定义一个类
5 static void Main(string[] args) 程序入口,args 是命令行参数数组
7-9 if (args.Length == 0) 如果没有参数,提示用户并退出
12 for (int i = 0; i < args.Length; i++) 遍历参数数组
13 Console.WriteLine(...) 输出每个参数

▶️运行方式及效果

1. 使用命令行运行(假设编译后的程序名为 MyApp.exe):
bash 复制代码
MyApp.exe Hello 123 true
2. 输出结果:
复制代码
你输入的命令行参数为:
参数 0:Hello
参数 1:123
参数 2:true

var关键字


🔍 什么是 var

在 C# 中,var 是一个 隐式类型局部变量声明关键字。它告诉编译器根据你赋值的内容自动推断变量的类型。

注意: var 并不是"无类型"或"动态类型",而是静态类型,只是类型由编译器自动推断。


✅代码示例

csharp 复制代码
using System;

class Program
{
    static void Main()
    {
        // 使用 var 声明变量并赋值
        var name = "Tom";          // 推断为 string
        var age = 25;              // 推断为 int
        var price = 9.99;          // 推断为 double
        var isActive = true;       // 推断为 bool
        var numbers = new int[] { 1, 2, 3 };  // 推断为 int[]
        
        // 输出变量类型和值
        Console.WriteLine($"name 类型: {name.GetType()}, 值: {name}");
        Console.WriteLine($"age 类型: {age.GetType()}, 值: {age}");
        Console.WriteLine($"price 类型: {price.GetType()}, 值: {price}");
        Console.WriteLine($"isActive 类型: {isActive.GetType()}, 值: {isActive}");
        Console.WriteLine($"numbers 类型: {numbers.GetType()}, 值: {string.Join(",", numbers)}");
    }
}

📝 注释说明

行号 代码片段 注释
8 var name = "Tom"; 编译器推断 namestring 类型
9 var age = 25; 推断为 int
10 var price = 9.99; 推断为 double(默认浮点数是 double)
11 var isActive = true; 推断为 bool
12 var numbers = new int[] { 1, 2, 3 }; 推断为 int[] 数组
14-18 Console.WriteLine(...) 输出变量的类型和值

⚠️ 三、使用限制

  • var 只能用于局部变量(不能用于类字段、属性等)。
  • 必须在声明时就赋值,否则无法推断类型:
csharp 复制代码
var x;     // ❌ 错误:必须有初始化表达式
x = 100;   // 依然报错

C# List集合


🧩什么是 List<T>

List<T> 是 C# 中一个非常常用的泛型集合类 ,位于 System.Collections.Generic 命名空间中。它类似于数组,但具有动态扩容能力,可以根据需要自动增加容量。

T 表示集合中元素的类型,如 intstring、自定义类等。


✅代码示例

csharp 复制代码
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        // 创建一个字符串类型的 List 集合
        List<string> names = new List<string>();

        // 添加元素
        names.Add("张三");
        names.Add("李四");
        names.Add("王五");

        // 插入元素到指定位置
        names.Insert(1, "赵六");

        // 访问元素(通过索引)
        Console.WriteLine("第一个名字是:" + names[0]);

        // 遍历集合
        Console.WriteLine("所有名字:");
        foreach (string name in names)
        {
            Console.WriteLine(name);
        }

        // 删除某个元素
        names.Remove("李四");

        // 检查是否存在某个元素
        if (names.Contains("张三"))
        {
            Console.WriteLine("张三在列表中");
        }

        // 获取集合长度
        Console.WriteLine("当前列表中有 " + names.Count + " 个元素");
    }
}

📝 注释说明

行号 代码片段 注释
5 using System.Collections.Generic; 引入泛型集合命名空间
8 List<string> names = new List<string>(); 创建一个空的字符串列表
10-13 Add() 方法 添加元素到列表末尾
16 Insert(1, "赵六") 在索引 1 处插入元素
19 names[0] 使用索引访问元素
22-26 foreach 循环 遍历列表中的每个元素
29 Remove("李四") 移除指定元素
32 Contains("张三") 判断是否包含某个元素
36 Count 属性 获取当前集合中元素的数量

🧱常用方法和属性一览

方法/属性 功能说明
Add(item) 添加一个元素到末尾
Insert(index, item) 在指定索引插入元素
Remove(item) 移除第一个匹配的元素
RemoveAt(index) 根据索引移除元素
Clear() 清空整个列表
Contains(item) 判断是否包含某个元素
Find(Predicate<T>) 查找符合条件的第一个元素
Sort() 对列表进行排序
Count 获取当前元素数量

C#丢弃


🧩什么是"丢弃"?

你可以把它理解为一个"垃圾桶",你不关心的数据就扔进去,不会占用内存变量名,也不会引发警告。

语法:_


✅ 代码示例

1. 忽略 out 参数
csharp 复制代码
string input = "123";
if (int.TryParse(input, out int number))
{
    Console.WriteLine("转换成功:" + number);
}
else
{
    Console.WriteLine("转换失败");
}

如果你只关心是否转换成功,而不关心具体值,可以这样写:

csharp 复制代码
if (int.TryParse(input, out _))
{
    Console.WriteLine("输入是一个有效的整数!");
}
else
{
    Console.WriteLine("输入无效!");
}

🔍 此处我们只关心是否解析成功,所以用 _ 丢弃实际解析结果。


2. 忽略元组(tuple)中的某些值
csharp 复制代码
(string name, int age, string city) GetUserInfo()
{
    return ("Tom", 25, "Shanghai");
}

var (_, _, city) = GetUserInfo(); // 只取 city,忽略 name 和 age
Console.WriteLine("所在城市:" + city);

3. 在 foreach 或 LINQ 查询中忽略不需要的变量
csharp 复制代码
List<string> names = new List<string> { "Alice", "Bob", "Charlie" };

foreach (var _ in names)
{
    Console.WriteLine("这是一个用户");
}

这样可以明确表达:我只关心循环次数,不关心每个元素本身。


4. 使用 _ 多次是合法的
csharp 复制代码
var (x, y) = (10, 20);
_ = x;
_ = y;

// 不会报错,因为多个丢弃变量都叫 `_` 是允许的

⚠️ 三、注意事项

内容 说明
_ 不是一个变量 不能给它赋值或读取它的值
不可变 它只是一个占位符,不代表真实数据
只能用于 C# 7.0 及以上版本 .NET Core 2.0 / .NET Framework 4.7+ 支持

C#的Range()方法

🧩什么是 Range() 方法?

虽然没有单独的 Range() 方法,但 C# 引入了 范围运算符 ..Range 结构,用于表示一个范围,并结合索引器来提取数据的一部分。

✅ 关键词:^ 表示倒数索引,.. 表示范围


✅代码示例

示例代码:

csharp 复制代码
using System;

class Program
{
    static void Main()
    {
        int[] numbers = { 10, 20, 30, 40, 50, 60 };

        // 使用 Range 提取索引 [1, 4) 的元素(即索引 1 到 3)
        var range1 = numbers[1..4];
        Console.WriteLine("range1: " + string.Join(", ", range1));  // 输出:20, 30, 40

        // 提取从索引 2 开始到末尾的所有元素
        var range2 = numbers[2..];
        Console.WriteLine("range2: " + string.Join(", ", range2));  // 输出:30, 40, 50, 60

        // 提取从开头到索引 3 的元素(不包含索引 3)
        var range3 = numbers[..3];
        Console.WriteLine("range3: " + string.Join(", ", range3));  // 输出:10, 20, 30

        // 使用 ^ 表示倒数索引:提取倒数第 3 个到倒数第 1 个(即索引 3 到 4)
        var range4 = numbers[^3..^1];
        Console.WriteLine("range4: " + string.Join(", ", range4));  // 输出:40, 50
    }
}

📝 注释说明

行号 代码片段 注释
7 int[] numbers = { ... } 定义一个整型数组
10 numbers[1..4] 提取从索引 1(含)到 4(不含)之间的元素
13 numbers[2..] 从索引 2 到末尾
16 numbers[..3] 从开始到索引 3(不含)
19 numbers[^3..^1] 使用 ^ 表示倒数索引:从倒数第 3 到倒数第 1(不含)

🔢关键概念:IndexRange

C# 8.0 引入两个新结构体:

类型 用途
System.Index 表示一个位置(支持正向和反向索引)
System.Range 表示一个范围 [start..end]

你可以这样使用它们:

csharp 复制代码
Index start = ^3;   // 倒数第三个
Index end = ^1;     // 倒数第一个(不包含)
Range range = start..end;

var result = numbers[range];
Console.WriteLine(string.Join(", ", result));

C#常数

🧩什么是 const 常数?

使用 const 关键字声明的变量,在编译时就被确定,并且其值在整个程序中不可更改

语法:public const 数据类型 常量名 = 值;


✅示例代码

csharp 复制代码
using System;

class Program
{
    // 定义常数
    public const double PI = 3.14159;
    public const string APP_NAME = "MyApp";
    public const int MaxUsers = 100;

    static void Main()
    {
        Console.WriteLine("圆周率 π = " + PI);
        Console.WriteLine("应用程序名称:" + APP_NAME);
        Console.WriteLine("最大用户数:" + MaxUsers);

        // 尝试修改常数? ❌ 编译错误!
        // PI = 3.14; // 报错:无法对静态只读字段赋值
    }
}

📝 注释说明

行号 代码片段 注释
7 public const double PI = 3.14159; 定义一个表示圆周率的常量
8 public const string APP_NAME = "MyApp"; 字符串常量
9 public const int MaxUsers = 100; 整型常量
12-16 Console.WriteLine(...) 输出常量值
18-19 PI = 3.14; ❌ 编译错误:常量不可修改

🔤支持的数据类型

C# 中 const 支持以下常用数据类型:

类型 示例
int const int Count = 10;
double / float const double Pi = 3.14;
string const string Title = "Hello";
bool const bool IsReady = true;
char const char Delimiter = ',';

⚠️ 注意:const 只能用于 基本数据类型 和某些特殊引用类型(如 string)。


🧱 四、常量与静态只读字段的区别(const vs static readonly

特性 const static readonly
编译时常量 ✅ 是 ❌ 否
运行时初始化 ❌ 不可 ✅ 可以
修改能力 ❌ 不可变 ❌ 初始化后不可变
适用类型 基本类型、字符串 所有类型
跨程序集更新影响 会保留旧值 会同步新值
示例对比:
csharp 复制代码
public class Settings
{
    public const string NameConst = "Tom";           // 编译时常量
    public static readonly string NameReadonly = "Jerry"; // 运行时常量
}

C#字符串格式

🧩C# 中字符串格式化的方法有哪些?

方法 特点
string.Format() 最基础的格式化方式
插值字符串($"..." C# 6.0 引入,推荐使用
Console.WriteLine() 内置支持 可直接格式化输出
ToString("格式字符串") 对数字、日期等进行格式化
StringBuilder.AppendFormat() 高效拼接时使用

✅1. 使用插值字符串(推荐)

这是目前最常用、也最直观的方式,使用 $"" 定义插值字符串。

示例:
csharp 复制代码
string name = "Tom";
int age = 25;
double height = 178.5;

// 使用插值字符串
string info = $"姓名:{name},年龄:{age},身高:{height:F1}cm";

Console.WriteLine(info);
输出:
复制代码
姓名:Tom,年龄:25,身高:178.5cm

🔍 {height:F1} 表示保留一位小数


✅2. 使用 string.Format()

适合需要延迟格式化或动态构造字符串的场景。

示例:
csharp 复制代码
string message = string.Format("姓名:{0},年龄:{1},身高:{2:F1}cm", name, age, height);
Console.WriteLine(message);
输出同上:
复制代码
姓名:Tom,年龄:25,身高:178.5cm

✅3. 格式化数字和日期

数字格式化(常见格式说明):
格式 示例 含义
F2 {value:F2} 保留两位小数
N0 {value:N0} 千分位整数
P1 {value:P1} 百分比,保留一位小数
C {value:C} 货币符号(根据区域自动)
示例:
csharp 复制代码
double price = 99.5;
double rate = 0.1234;

Console.WriteLine($"价格:{price:C}");         // ¥99.50 或 $99.50
Console.WriteLine($"折扣率:{rate:P1}");       // 12.3%

日期时间格式化:
csharp 复制代码
DateTime now = DateTime.Now;

Console.WriteLine($"完整日期时间:{now:yyyy-MM-dd HH:mm:ss}");
Console.WriteLine($"简写日期:{now:yyyy/MM/dd}");

✅4. 使用 ToString() 格式化

适用于单个变量格式化为字符串:

csharp 复制代码
double value = 1234.5678;

string formattedValue = value.ToString("N2");   // 输出:1,234.57
string percent = (0.876).ToString("P1");        // 输出:87.6%

C#字符串插值

🧩什么是字符串插值?

C# 6.0 引入了 字符串插值(Interpolated Strings) ,使用 $"" 语法,允许你在字符串中直接嵌入变量或表达式,使代码更清晰易读。

语法:$"..."


✅ 二、基本使用示例

csharp 复制代码
using System;

class Program
{
    static void Main()
    {
        string name = "Tom";
        int age = 25;
        double height = 178.5;

        // 使用插值字符串输出信息
        Console.WriteLine($"姓名:{name},年龄:{age},身高:{height:F1}cm");
    }
}

输出:

复制代码
姓名:Tom,年龄:25,身高:178.5cm

📝逐行注释解释

行号 代码片段 注释
1 using System; 引入基础命名空间
3 class Program 定义主类
5 static void Main() 程序入口
7-9 string name = "..."; int age = ...; 声明变量
12 Console.WriteLine($"...") 插值字符串,内嵌变量和格式化

相关推荐
*neverGiveUp*11 分钟前
PHP基础知识
开发语言·php
課代表16 分钟前
AcroForm JavaScript Promise 对象应用示例: 异步加载PDF文件
开发语言·javascript·pdf·promise·对象
我是Superman丶25 分钟前
【Lua】java 调用redis执行 lua脚本
java·开发语言·junit
明月看潮生1 小时前
青少年编程与数学 02-019 Rust 编程基础 14课题、并发编程
开发语言·青少年编程·rust·编程与数学
Warren981 小时前
Java面试八股Spring篇(4500字)
java·开发语言·spring boot·后端·spring·面试
晚秋大魔王1 小时前
OpenHarmony 开源鸿蒙南向开发——linux下使用make交叉编译第三方库——gnutls
java·开发语言
EelBarb1 小时前
python:一个代理流量监控的媒体文件下载脚本
开发语言·python
背帆2 小时前
go的interface接口底层实现
开发语言·后端·golang
小屁孩大帅-杨一凡2 小时前
一个简单点的js的h5页面实现地铁快跑的小游戏
开发语言·前端·javascript·css·html