Skip to content

C# - 基本语法

C# 是一门现代的、面向对象的、类型安全的编程语言。在面向对象编程(Object-Oriented Programming, OOP)范式中,程序由相互交互的各种对象组成。这些交互通过方法(methods,即行为)执行,数据则存储在属性(properties)或字段(fields,即特性)中。相同类型的对象属于同一个类(class)。

从 .NET 6 开始,C# 引入了顶级语句(top-level statements),这简化了新程序的代码。您不再需要手动声明 Program 类或 Main 方法。下面是最简单的 C# 程序:

// 这一行代码就是一个完整可运行的 C# 程序!
Console.WriteLine("Hello, Modern C# World!");

如何运行:

  1. 安装 .NET SDK。
  2. 创建一个名为 Program.cs 的文件,并添加上述代码。
  3. 在文件所在目录中打开终端,运行 dotnet run。

这种现代方法更简洁,对初学者也更友好。

虽然顶级语句非常适合简单的程序,但理解经典的类结构对于构建大型应用程序至关重要。让我们看一个现代化的 Rectangle 类示例。

此示例演示了 C# 中的关键特性,例如类中的属性、构造函数和方法。请注意 Rectangle 的逻辑与程序的执行流程之间清晰的分离。

using System;
// 使用文件范围的命名空间,代码更整洁(C# 10+)
namespace GeometryExample;
// Rectangle 类的定义
public class Rectangle
{
// 自动实现的属性是定义字段的现代方式
public double Length { get; set; }
public double Width { get; set; }
// 用于初始化新 Rectangle 对象的构造函数
public Rectangle(double length, double width)
{
// 基本验证
if (length <= 0 || width <= 0)
{
throw new ArgumentException("Length and width must be positive.");
}
Length = length;
Width = width;
}
// 使用属性计算面积的方法
public double CalculateArea()
{
return Length * Width;
}
// 重写 ToString() 方法以获得有用的字符串表示
public override string ToString()
{
// 字符串插值 ($) 是格式化字符串的现代方式
return $"Rectangle (Length: {Length}, Width: {Width})";
}
}
// 使用顶级语句的主执行逻辑
// 创建 Rectangle 类的实例
var myRectangle = new Rectangle(4.5, 3.5);
// 使用重写的 ToString() 方法显示详细信息
Console.WriteLine(myRectangle.ToString());
// 计算并显示面积
var area = myRectangle.CalculateArea();
Console.WriteLine($"Area: {area}");
// 错误处理示例
try
{
var invalidRectangle = new Rectangle(-1, 5);
}
catch (ArgumentException ex)
{
Console.WriteLine($"Error creating rectangle: {ex.Message}");
}

编译并执行上述代码后,会产生以下结果:

Rectangle (Length: 4.5, Width: 3.5)
Area: 15.75
Error creating rectangle: Length and width must be positive.

C# 区分大小写。myVariable 和 MyVariable 是两个不同的变量。约定俗成地,局部变量使用小驼峰命名法(camelCase,如 myVariable),而类、方法和属性等公共成员使用大驼峰命名法(PascalCase,如 MyRectangle)。

C# 中的每个语句都必须以分号 ; 结尾。它标志着一条命令的结束。

花括号定义了一个作用域或代码块。它们用于命名空间、类、方法和控制流语句(如 if、for、while)。

注释会被编译器忽略,用于解释代码。

  • // 用于单行注释。
  • /* ... */ 用于多行注释。
  • /// 用于 XML 文档注释,在集成开发环境(IDE)中提供 IntelliSense 信息。
/// <summary>
/// 这是 Rectangle 类的 XML 注释。
/// 它会出现在 Visual Studio 的工具提示中。
/// </summary>
public class Rectangle { /*...*/ }

using 指令允许您使用命名空间中的类型,而无需指定它们的完整名称。例如,using System; 让您可以编写 Console.WriteLine() 而不是 System.Console.WriteLine()。现代 .NET 项目经常使用隐式 using(implicit usings),其中常用命名空间会由构建过程自动包含,从而减少样板代码。

class 关键字用于声明一个类,类是创建对象的蓝图。

标识符是您赋予类、变量、方法等的名称。标识符的规则:

  • 必须以字母或下划线 (_) 开头。
  • 可以包含字母、数字和下划线。
  • 不能是 C# 关键字(除非前面加上 @,例如 @class)。

关键字是具有特殊含义的保留字,对编译器而言具有特殊意义。除非带有 @ 前缀,否则不能将它们用作标识符。

保留关键字
abstract
catch
default
explicit
foreach
internal
object
public
sizeof
throw
unsafe
上下文关键字
add
descending
init
or
select
with

这些语句根据布尔条件控制程序流程。

int age = 20;
if (age >= 18)
{
Console.WriteLine("You are eligible to vote.");
}
else
{
Console.WriteLine("You are not eligible to vote.");
}
// 输出:You are eligible to vote.
for (int i = 1; i <= 3; i++)
{
Console.WriteLine($"Iteration: {i}");
}
// 输出:
// Iteration: 1
// Iteration: 2
// Iteration: 3
int count = 1;
while (count <= 3)
{
Console.WriteLine($"Count: {count}");
count++;
}
// 输出:
// Count: 1
// Count: 2
// Count: 3

使用 Console.WriteLine() 将文本打印到控制台。现代 C# 倾向于使用字符串插值($)进行格式化。

string framework = "C#";
Console.WriteLine($"Welcome to modern {framework}!");
// 输出:Welcome to modern C#!

Console.ReadLine() 从用户读取一行文本。它总是返回一个字符串,该字符串可能是 null。

Console.Write("Enter your name: ");
string? name = Console.ReadLine(); // string? 表示它可能是 null
Console.WriteLine($"Hello, {name ?? "stranger"}!");

使用 try-catch 块优雅地处理运行时错误。最佳实践是捕获 FormatException 等特定异常,而不是通用的 Exception。

Console.Write("Enter a number: ");
string? input = Console.ReadLine();
try
{
int number = Convert.ToInt32(input);
Console.WriteLine($"You entered: {number}");
}
catch (FormatException)
{
Console.WriteLine("Error: That was not a valid number.");
}
catch (Exception ex) // 捕获其他潜在错误
{
Console.WriteLine($"An unexpected error occurred: {ex.Message}");
}
  • 使用有意义的名称:为变量、方法和类选择描述性名称(例如,使用 customerName 而不是 cn)。
  • 遵循命名约定:局部变量使用 camelCase(小驼峰命名),类、方法和属性使用 PascalCase(大驼峰命名)。
  • 倾向于不可变性:在可能的情况下,使数据创建后只读,以防止错误。使用 readonly 字段或 init-only 属性。
  • 使用 var 提高可读性:当从赋值的右侧可以明显看出类型时,使用 var 关键字声明局部变量(例如,var user = new User();)。
  • 拥抱 LINQ:使用 Language-Integrated Query (LINQ) 进行强大且可读的数据操作。
  • 编写小而集中的方法:每个方法都应该只做好一件事。这可以提高可测试性和可读性。
  • 优雅地处理错误:不要忽略异常。使用 try-catch 块来处理预期错误,并确保您的应用程序保持稳定。