C# 语言教程:语法、特性与应用详解
C# 语言教程:语法、特性与应用详解
C#(读作 "C Sharp")是由微软开发的一种现代、通用、面向对象的编程语言。它在 .NET 框架(现在主要是 .NET)上运行,也可用于跨平台的 .NET Core(现已合并为 .NET 5 及更高版本)开发。C# 以其强大的功能、类型安全、可扩展性和广泛的应用领域而闻名。本教程将深入探讨 C# 的语法、关键特性以及在各种应用场景中的实际应用。
一、C# 语言基础
1.1 第一个 C# 程序:Hello, World!
让我们从经典的 "Hello, World!" 程序开始,了解 C# 程序的基本结构:
```csharp
using System;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
}
}
```
代码解析:
using System;
:using
关键字用于导入命名空间。System
命名空间包含了许多常用的类和方法,如Console
类。class Program
: C# 是面向对象的语言,所有代码都必须位于类中。Program
是我们定义的类名。static void Main(string[] args)
:Main
方法是程序的入口点。static
: 表示Main
方法是静态的,可以直接通过类名调用,无需创建类的实例。void
: 表示Main
方法不返回任何值。string[] args
:Main
方法可以接收一个字符串数组作为命令行参数。
Console.WriteLine("Hello, World!");
:Console.WriteLine
方法用于在控制台输出文本。
1.2 数据类型
C# 是一种强类型语言,每个变量都必须声明其数据类型。C# 的数据类型分为值类型和引用类型。
值类型 (Value Types): 值类型直接存储数据。
- 整数类型:
int
: 32 位有符号整数 (常用)long
: 64 位有符号整数short
: 16 位有符号整数byte
: 8 位无符号整数sbyte
: 8 位有符号整数uint
: 32 位无符号整数ulong
: 64 位无符号整数ushort
: 16 位无符号整数
- 浮点数类型:
float
: 32 位单精度浮点数double
: 64 位双精度浮点数 (常用)decimal
: 128 位高精度十进制数 (用于金融计算)
- 字符类型:
char
: 16 位 Unicode 字符
- 布尔类型:
bool
: 表示真 (true) 或假 (false)
- 结构体(struct): 用户自定义值类型.
- 枚举(enum): 一组命名的整数常量.
引用类型 (Reference Types): 引用类型存储数据的内存地址。
- 类 (class): 面向对象编程的核心,用于定义对象的蓝图。
- 接口 (interface): 定义一组方法、属性、事件和索引器,但不提供实现。
- 数组 (array): 存储相同类型元素的集合。
- 字符串 (string): 表示文本。
- 委托 (delegate): 类型安全的函数指针。
- 对象 (object): 所有类型的基类。
示例:
```csharp
int age = 30;
double price = 99.99;
char grade = 'A';
bool isEnabled = true;
string name = "John Doe";
int[] numbers = { 1, 2, 3, 4, 5 };
// 结构体示例
struct Point
{
public int X;
public int Y;
}
Point p = new Point { X = 10, Y = 20};
//枚举示例
enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
Days today = Days.Wed;
```
1.3 变量和常量
-
变量: 使用数据类型声明,用于存储数据。
csharp
int myVariable = 10;
myVariable = 20; // 可以改变变量的值 -
常量: 使用
const
关键字声明,一旦赋值后不能更改。
csharp
const double Pi = 3.14159;
// Pi = 3.14; // 错误:不能修改常量的值 -
只读字段: 使用
readonly
关键字声明, 只能在声明时或者构造函数中初始化.
```csharp
class MyClass
{
readonly int myReadonlyField = 5;
public MyClass(int val)
{
myReadonlyField = val; //可以在构造函数中赋值
}
}```
1.4 运算符
C# 提供了丰富的运算符,用于执行各种操作。
- 算术运算符:
+
,-
,*
,/
,%
(取模) - 关系运算符:
==
,!=
,>
,<
,>=
,<=
- 逻辑运算符:
&&
(与),||
(或),!
(非) - 赋值运算符:
=
,+=
,-=
,*=
,/=
,%=
- 位运算符:
&
(按位与),|
(按位或),^
(按位异或),~
(按位取反),<<
(左移),>>
(右移) - 条件运算符 (三元运算符):
condition ? expression1 : expression2
- 类型运算符:
is
,as
,typeof
- 空合并运算符:
??
,??=
示例:
```csharp
int a = 10;
int b = 5;
int sum = a + b; // 15
bool isEqual = a == b; // false
bool result = (a > b) && (b > 0); // true
int max = (a > b) ? a : b; // 10
string str = null;
string str2 = str ?? "default value"; // str2 的值为 "default value"
```
1.5 控制流语句
控制流语句用于控制程序的执行流程。
-
条件语句:
if-else
: 根据条件执行不同的代码块。switch
: 根据表达式的值执行不同的 case。
-
循环语句:
for
: 循环执行固定次数的代码块。while
: 当条件为真时循环执行代码块。do-while
: 至少执行一次代码块,然后在条件为真时继续循环。foreach
: 遍历集合中的每个元素。
示例:
```csharp
// if-else
int num = 10;
if (num > 0)
{
Console.WriteLine("Positive");
}
else if (num < 0)
{
Console.WriteLine("Negative");
}
else
{
Console.WriteLine("Zero");
}
// switch
int day = 3;
switch (day)
{
case 1:
Console.WriteLine("Monday");
break;
case 2:
Console.WriteLine("Tuesday");
break;
// ... other cases
default:
Console.WriteLine("Invalid day");
break;
}
// for
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
}
// while
int count = 0;
while (count < 5)
{
Console.WriteLine(count);
count++;
}
// foreach
int[] numbers = { 1, 2, 3, 4, 5 };
foreach (int number in numbers)
{
Console.WriteLine(number);
}
```
1.6 方法(函数)
方法是执行特定任务的代码块。
```csharp
// 定义一个方法
int Add(int x, int y)
{
return x + y;
}
// 调用方法
int result = Add(5, 3); // result = 8
```
-
参数传递:
- 值传递 (by value): 将参数的副本传递给方法,方法内对参数的修改不会影响原始变量。
- 引用传递 (by reference): 使用
ref
关键字,将参数的内存地址传递给方法,方法内对参数的修改会影响原始变量。 - 输出传递 (by output): 使用
out
关键字, 方法必须对该参数赋值, 调用前可以不初始化.
-
方法重载: 同一个类中可以有多个同名方法,但参数列表必须不同(参数类型、数量或顺序)。
-
可选参数: 使用
=
为参数提供默认值. - 命名参数: 调用方法时可以指定参数名称.
```csharp
void MyMethod(int a, int b = 10, string c = "hello") { ... }
MyMethod(5); // a=5, b=10, c="hello"
MyMethod(5, 20); // a=5, b=20, c="hello"
MyMethod(5, c: "world"); // a=5, b=10, c="world"
```
二、C# 面向对象编程 (OOP)
C# 是一种面向对象的语言,支持 OOP 的四大原则:封装、继承、多态和抽象。
2.1 类和对象
- 类 (Class): 类是对象的蓝图,定义了对象的属性(数据)和方法(行为)。
- 对象 (Object): 对象是类的实例。
```csharp
// 定义一个 Person 类
class Person
{
// 属性
public string Name;
public int Age;
// 方法
public void SayHello()
{
Console.WriteLine("Hello, my name is " + Name + " and I am " + Age + " years old.");
}
}
// 创建 Person 对象
Person person1 = new Person();
person1.Name = "Alice";
person1.Age = 25;
person1.SayHello();
Person person2 = new Person { Name = "Bob", Age = 30 };
person2.SayHello();
```
2.2 构造函数
构造函数是特殊的类方法,用于创建和初始化对象。
- 构造函数与类同名,没有返回类型。
- 可以有多个构造函数(构造函数重载)。
- 如果没有定义构造函数,编译器会自动提供一个默认的无参构造函数。
```csharp
class Person
{
public string Name;
public int Age;
// 构造函数
public Person(string name, int age)
{
Name = name;
Age = age;
}
// 无参构造函数
public Person()
{
Name = "Unknown";
Age = 0;
}
}
Person person1 = new Person("Alice", 25);
Person person2 = new Person(); // 使用无参构造函数
```
2.3 封装 (Encapsulation)
封装是将数据和方法组合到一个类中,并控制对数据的访问。
- 访问修饰符:
public
: 任何地方都可以访问。private
: 只能在类内部访问。protected
: 只能在类内部和派生类中访问。internal
: 只能在同一个程序集中访问。protected internal
:protected
和internal
的组合.
- 属性 (Properties): 属性提供了一种更灵活、更安全的方式来访问和修改字段的值。属性通常包含
get
和set
访问器。
```csharp
class Person
{
private string name; // 私有字段
private int age;
// 属性
public string Name
{
get { return name; }
set { name = value; }
}
public int Age
{
get { return age; }
set
{
if (value >= 0)
{
age = value;
}
else
{
Console.WriteLine("Age cannot be negative.");
}
}
}
}
```
2.4 继承 (Inheritance)
继承允许一个类(派生类)从另一个类(基类)继承属性和方法。
- 使用
:
符号表示继承关系。 - 派生类可以添加新的属性和方法,也可以重写基类的方法。
- C# 不支持多重继承(一个类只能继承一个基类),但支持多接口实现。
```csharp
// 基类
class Animal
{
public string Name { get; set; }
public virtual void MakeSound() // 虚方法,允许派生类重写
{
Console.WriteLine("Generic animal sound");
}
}
// 派生类
class Dog : Animal
{
// 重写基类的方法
public override void MakeSound()
{
Console.WriteLine("Woof!");
}
}
class Cat : Animal
{
public override void MakeSound()
{
Console.WriteLine("Meow!");
}
}
Animal animal = new Animal();
animal.MakeSound(); // Generic animal sound
Dog dog = new Dog();
dog.MakeSound(); // Woof!
Cat cat = new Cat();
cat.MakeSound(); // Meow!
```
2.5 多态 (Polymorphism)
多态是指不同对象对同一消息(方法调用)做出不同响应的能力。
- 方法重写 (override): 派生类重写基类的虚方法 (virtual) 或抽象方法 (abstract)。
- 抽象类 (abstract class): 抽象类不能被实例化,只能被继承。抽象类可以包含抽象方法(没有实现的方法),派生类必须实现这些抽象方法。
- 接口 (interface): 接口定义了一组方法、属性、事件和索引器,但不提供实现。类可以实现多个接口。
```csharp
// 抽象类
abstract class Shape
{
public abstract double Area(); // 抽象方法
}
// 派生类
class Circle : Shape
{
public double Radius { get; set; }
public override double Area()
{
return Math.PI * Radius * Radius;
}
}
class Rectangle : Shape
{
public double Width { get; set; }
public double Height { get; set; }
public override double Area()
{
return Width * Height;
}
}
// 接口
interface IDrawable
{
void Draw();
}
// 类实现接口
class Circle : Shape, IDrawable
{
// ... 省略其他代码
public void Draw()
{
Console.WriteLine("Drawing a circle");
}
}
// 多态
Shape shape1 = new Circle { Radius = 5 };
Shape shape2 = new Rectangle { Width = 4, Height = 6 };
Console.WriteLine(shape1.Area()); // 调用 Circle 的 Area 方法
Console.WriteLine(shape2.Area()); // 调用 Rectangle 的 Area 方法
IDrawable drawable = new Circle {Radius = 3};
drawable.Draw(); // Drawing a circle
```
三、C# 高级特性
3.1 泛型 (Generics)
泛型允许编写可以处理多种数据类型的代码,而无需为每种类型编写单独的代码。
```csharp
// 泛型类
class MyList
{
private T[] items;
public MyList(int capacity)
{
items = new T[capacity];
}
public void Add(T item)
{
// ... 添加元素到数组
}
public T Get(int index)
{
return items[index];
}
}
// 使用泛型类
MyList
intList.Add(5);
int num = intList.Get(0);
MyList
stringList.Add("Hello");
string str = stringList.Get(0);
```
3.2 委托 (Delegates) 和事件 (Events)
- 委托 (Delegate): 委托是类型安全的函数指针,可以引用具有相同签名的方法。
- 事件 (Event): 事件是基于委托的,用于在对象状态发生变化时通知其他对象。
```csharp
// 定义委托
delegate void MyDelegate(string message);
class Publisher
{
// 定义事件
public event MyDelegate MyEvent;
public void DoSomething()
{
// ... 执行一些操作
if (MyEvent != null)
{
MyEvent("Something happened!"); // 触发事件
}
}
}
class Subscriber
{
public void HandleEvent(string message)
{
Console.WriteLine("Received message: " + message);
}
}
// 使用委托和事件
Publisher publisher = new Publisher();
Subscriber subscriber = new Subscriber();
// 订阅事件
publisher.MyEvent += subscriber.HandleEvent;
//可以取消订阅
//publisher.MyEvent -= subscriber.HandleEvent;
publisher.DoSomething(); // Received message: Something happened!
```
3.3 Lambda 表达式
Lambda 表达式是一种简洁的匿名函数,常用于委托和 LINQ 查询。
```csharp
// Lambda 表达式作为委托
MyDelegate myDelegate = (message) => { Console.WriteLine(message); };
myDelegate("Hello from Lambda!");
// Lambda 表达式用于 LINQ 查询
int[] numbers = { 1, 2, 3, 4, 5 };
var evenNumbers = numbers.Where(n => n % 2 == 0); // 筛选偶数
foreach (int num in evenNumbers)
{
Console.WriteLine(num); // 2, 4
}
```
3.4 LINQ (Language Integrated Query)
LINQ 是一种强大的查询语言,可以用于查询各种数据源,如集合、数组、数据库、XML 等。
```csharp
// LINQ 查询
List
// 查询语法
var query = from n in numbers
where n > 2
orderby n descending
select n;
// 方法语法
var query2 = numbers.Where(n => n > 2).OrderByDescending(n => n);
foreach (int num in query)
{
Console.WriteLine(num); // 5, 4, 3
}
```
3.5 异步编程 (async/await)
async
和 await
关键字用于编写异步代码,可以提高应用程序的响应能力,特别是在处理 I/O 密集型操作时。
```csharp
async Task
{
using (var client = new HttpClient())
{
// 异步下载字符串
string result = await client.GetStringAsync(url);
return result;
}
}
// 调用异步方法
async Task MyMethod()
{
string content = await DownloadStringAsync("https://www.example.com");
Console.WriteLine(content.Substring(0, 100)); // 显示前 100 个字符
}
//在Main方法中调用 (C# 7.1及以上)
static async Task Main(string[] args)
{
await MyMethod();
}
```
3.6 特性 (Attributes)
特性是添加到代码元素(如类、方法、属性等)的元数据。可以用于指示编译器或运行时执行某些操作。
```C#
[Serializable] //指示该类可以被序列化
class MyClass
{
[Obsolete("This method is deprecated. Use NewMethod instead.")] //指示方法已过时
public void OldMethod() { ... }
public void NewMethod() { ... }
}
```
四、C# 应用领域
C# 是一种用途广泛的编程语言,可用于开发各种类型的应用程序:
- 桌面应用程序: Windows Forms, WPF (Windows Presentation Foundation)
- Web 应用程序: ASP.NET Core (MVC, Razor Pages, Web API), Blazor
- 移动应用程序: Xamarin (跨平台), .NET MAUI (.NET Multi-platform App UI)
- 游戏开发: Unity (游戏引擎)
- 云服务: Azure Functions, Azure App Service
- 物联网 (IoT) 应用: .NET IoT Libraries
- 机器学习: ML.NET
- 命令行工具
五、总结
C# 是一种功能强大、易于学习且应用广泛的编程语言。本教程详细介绍了 C# 的语法、面向对象编程、高级特性以及各种应用领域。掌握 C# 将为您打开通往软件开发世界的大门,让您能够构建各种类型的应用程序。
这只是一个开始,C# 还有很多高级主题和库等待您去探索,例如:反射、表达式树、并行编程、动态编程、COM 互操作等。希望本教程能为您提供坚实的 C# 基础,并激发您继续学习和探索的兴趣。 持续练习、阅读文档和参与开源项目是提高 C# 技能的最佳途径。