C# 编程指南:从入门到精通 – wiki基地


C# 编程指南:从入门到精通

C#(读作 C-sharp)是由微软开发的一种现代、通用、面向对象的编程语言。它在 .NET 平台上运行,广泛应用于开发各种应用程序,包括桌面应用(使用 WPF 或 WinForms)、Web 应用(使用 ASP.NET Core)、移动应用(使用 Xamarin 或 .NET MAUI)、游戏开发(使用 Unity)以及云服务等。本指南将带你从 C# 的基础知识开始,逐步深入到高级概念和实践。

第一部分:C# 入门

1.1 什么是 C# 和 .NET?

C# 是一种静态类型语言,语法与 C++ 和 Java 类似,易于学习。它编译为中间语言(IL),然后在 .NET 运行时(CLR)上执行。
.NET 是一个免费的、开源的开发平台,用于构建多种应用程序。它包含运行时、库、编译器等工具,支持多种语言,其中 C# 是其主要语言。

1.2 安装开发环境

要开始 C# 编程,你需要安装:
Visual Studio CodeVisual Studio:强大的集成开发环境(IDE)。推荐使用 Visual Studio Community 版,它功能更全面,对初学者友好。
.NET SDK:包含编译和运行 C# 应用程序所需的工具和运行时。

1.3 你的第一个 C# 程序:Hello World

创建一个新的控制台应用程序。在 Visual Studio 中,选择“创建新项目” -> “控制台应用程序”。

“`csharp
// Program.cs
using System; // 引入System命名空间,包含Console类

namespace HelloWorld // 定义命名空间,组织代码
{
class Program // 定义类,程序的入口点通常在此
{
static void Main(string[] args) // Main方法是程序的入口
{
// Console.WriteLine用于向控制台输出文本
Console.WriteLine(“Hello, World!”);
Console.ReadKey(); // 等待用户按键,防止控制台立即关闭
}
}
}
``
运行此程序,你将在控制台看到
Hello, World!`。

1.4 基本语法和数据类型

C# 是强类型语言,这意味着你必须在使用变量之前声明其类型。

常用数据类型:
int: 整数(如 10, -5)
double: 双精度浮点数(如 3.14, 2.0)
float: 单精度浮点数(如 3.14f)
decimal: 高精度十进制数(用于货币计算)
bool: 布尔值(truefalse
char: 单个字符(如 ‘A’, ‘b’)
string: 字符串(如 “Hello”, “C#”)

变量声明:
csharp
int age = 30;
string name = "Alice";
bool isActive = true;
double price = 19.99;

1.5 运算符

C# 支持常见的算术、比较、逻辑、赋值等运算符。
算术运算符: +, -, *, /, %
比较运算符: ==, !=, >, <, >=, <=
逻辑运算符: && (与), || (或), ! (非)
赋值运算符: =, +=, -=, *=

1.6 控制流语句

  • 条件语句: if, else if, else, switch
    “`csharp
    int score = 85;
    if (score >= 90)
    {
    Console.WriteLine(“优秀”);
    }
    else if (score >= 60)
    {
    Console.WriteLine(“及格”);
    }
    else
    {
    Console.WriteLine(“不及格”);
    }

string day = “Monday”;
switch (day)
{
case “Monday”:
Console.WriteLine(“周一”);
break;
case “Tuesday”:
Console.WriteLine(“周二”);
break;
default:
Console.WriteLine(“其他”);
break;
}
- **循环语句:** `for`, `while`, `do-while`, `foreach`csharp
for (int i = 0; i < 5; i++)
{
Console.WriteLine($”For 循环: {i}”);
}

int j = 0;
while (j < 3)
{
Console.WriteLine($”While 循环: {j}”);
j++;
}

string[] fruits = { “Apple”, “Banana”, “Cherry” };
foreach (string fruit in fruits)
{
Console.WriteLine($”水果: {fruit}”);
}
“`

第二部分:面向对象编程 (OOP)

C# 是一种纯粹的面向对象语言,OOP 是其核心。

2.1 类和对象

类 (Class) 是创建对象的蓝图或模板。它定义了对象的属性(字段/变量)和行为(方法/函数)。
对象 (Object) 是类的实例。

“`csharp
// 定义一个 Person 类
class Person
{
// 属性 (Property)
public string Name { get; set; }
public int Age { get; set; }

// 构造函数 (Constructor)
public Person(string name, int age)
{
    Name = name;
    Age = age;
}

// 方法 (Method)
public void Introduce()
{
    Console.WriteLine($"大家好,我叫 {Name},今年 {Age} 岁。");
}

}

// 创建对象并使用
class Program
{
static void Main(string[] args)
{
Person person1 = new Person(“张三”, 25); // 创建 Person 对象
person1.Introduce(); // 调用对象方法

    Person person2 = new Person("李四", 30);
    person2.Introduce();
}

}
“`

2.2 封装 (Encapsulation)

封装是将数据(属性)和操作数据的方法(行为)绑定在一起,并隐藏对象的内部状态。通过访问修饰符(public, private, protected, internal)来控制成员的可见性。
public: 任何地方都可以访问。
private: 只能在当前类内部访问。
protected: 只能在当前类及其派生类中访问。
internal: 只能在当前程序集内访问。

通常,字段会设为 private,并通过 public 属性(Property)来提供受控的访问。

“`csharp
class BankAccount
{
private decimal _balance; // 私有字段

public decimal Balance // 公有属性,提供受控访问
{
    get { return _balance; }
    private set { _balance = value; } // 只能在类内部设置
}

public BankAccount(decimal initialBalance)
{
    Balance = initialBalance;
}

public void Deposit(decimal amount)
{
    if (amount > 0)
    {
        Balance += amount;
        Console.WriteLine($"存入 {amount} 元。当前余额:{Balance}");
    }
}

public void Withdraw(decimal amount)
{
    if (amount > 0 && Balance >= amount)
    {
        Balance -= amount;
        Console.WriteLine($"取出 {amount} 元。当前余额:{Balance}");
    }
    else
    {
        Console.WriteLine("取款失败:余额不足或金额无效。");
    }
}

}
“`

2.3 继承 (Inheritance)

继承允许一个类(子类/派生类)从另一个类(父类/基类)继承属性和方法,从而实现代码重用和层次结构。使用 : 符号表示继承。

“`csharp
// 基类
class Animal
{
public string Name { get; set; }

public Animal(string name)
{
    Name = name;
}

public void Eat()
{
    Console.WriteLine($"{Name} 正在吃东西。");
}

}

// 派生类 Dog 继承自 Animal
class Dog : Animal
{
public Dog(string name) : base(name) // 调用基类构造函数
{
}

public void Bark()
{
    Console.WriteLine($"{Name} 汪汪叫!");
}

}

class Program
{
static void Main(string[] args)
{
Dog myDog = new Dog(“旺财”);
myDog.Eat(); // 继承自 Animal
myDog.Bark(); // Dog 自己的方法
}
}
“`

2.4 多态 (Polymorphism)

多态意味着对象可以根据其类型以不同的方式响应相同的方法调用。主要通过方法重写(override)和接口实现。
方法重写: 基类中的方法被标记为 virtual,派生类中使用 override 关键字提供自己的实现。
抽象类和抽象方法: 抽象类不能被实例化,包含抽象方法(无实现,必须在派生类中实现)。
接口 (Interface): 定义了一组行为契约,类可以实现接口,从而保证实现这些行为。一个类可以实现多个接口。

“`csharp
// 多态示例:方法重写
class Shape
{
public virtual void Draw() // 虚方法
{
Console.WriteLine(“绘制一个通用形状”);
}
}

class Circle : Shape
{
public override void Draw() // 重写 Draw 方法
{
Console.WriteLine(“绘制一个圆形”);
}
}

class Rectangle : Shape
{
public override void Draw() // 重写 Draw 方法
{
Console.WriteLine(“绘制一个矩形”);
}
}

// 接口示例
interface ILogger
{
void Log(string message);
}

class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine($”[Console] {message}”);
}
}

class FileLogger : ILogger
{
public void Log(string message)
{
// 实际应用中会写入文件
Console.WriteLine($”[File] {message}”);
}
}

class Program
{
static void Main(string[] args)
{
Shape s1 = new Circle();
Shape s2 = new Rectangle();
Shape s3 = new Shape();

    s1.Draw(); // 输出:绘制一个圆形
    s2.Draw(); // 输出:绘制一个矩形
    s3.Draw(); // 输出:绘制一个通用形状

    ILogger logger1 = new ConsoleLogger();
    ILogger logger2 = new FileLogger();

    logger1.Log("这是一条控制台日志");
    logger2.Log("这是一条文件日志");
}

}
“`

第三部分:C# 进阶概念

3.1 异常处理 (Exception Handling)

使用 try-catch-finally 块来处理运行时错误,防止程序崩溃。

csharp
try
{
int a = 10;
int b = 0;
int result = a / b; // 会抛出 DivideByZeroException
Console.WriteLine(result);
}
catch (DivideByZeroException ex)
{
Console.WriteLine($"除零错误:{ex.Message}");
}
catch (Exception ex) // 捕获所有其他异常
{
Console.WriteLine($"发生未知错误:{ex.Message}");
}
finally
{
Console.WriteLine("无论是否发生异常,都会执行此代码块。");
}

3.2 泛型 (Generics)

泛型允许你定义类型参数化的类、方法、接口和委托,从而创建可重用、类型安全且高性能的代码。

“`csharp
class MyGenericList // T 是类型参数
{
private T[] _items;
private int _count;

public MyGenericList(int capacity)
{
    _items = new T[capacity];
    _count = 0;
}

public void Add(T item)
{
    if (_count < _items.Length)
    {
        _items[_count++] = item;
    }
    else
    {
        Console.WriteLine("列表已满。");
    }
}

public T Get(int index)
{
    if (index >= 0 && index < _count)
    {
        return _items[index];
    }
    throw new IndexOutOfRangeException();
}

}

class Program
{
static void Main(string[] args)
{
MyGenericList intList = new MyGenericList(5);
intList.Add(10);
intList.Add(20);
Console.WriteLine($”第一个元素: {intList.Get(0)}”);

    MyGenericList<string> stringList = new MyGenericList<string>(5);
    stringList.Add("Hello");
    stringList.Add("World");
    Console.WriteLine($"第一个元素: {stringList.Get(0)}");
}

}
“`

3.3 委托 (Delegates) 和 事件 (Events)

  • 委托: 是一种类型安全的函数指针,可以引用一个或多个方法。它是实现事件的基础。
  • 事件: 是一种通知机制,允许对象在发生特定动作时通知其他对象。

“`csharp
// 委托定义
public delegate void MyDelegate(string message);

class Publisher
{
// 事件定义
public event MyDelegate OnMessageSent;

public void SendMessage(string message)
{
    Console.WriteLine($"Publisher 发送消息: {message}");
    OnMessageSent?.Invoke(message); // 触发事件
}

}

class Subscriber
{
private string _name;

public Subscriber(string name)
{
    _name = name;
}

public void OnEventHandler(string message)
{
    Console.WriteLine($"Subscriber {_name} 接收到消息: {message}");
}

}

class Program
{
static void Main(string[] args)
{
Publisher publisher = new Publisher();
Subscriber sub1 = new Subscriber(“A”);
Subscriber sub2 = new Subscriber(“B”);

    // 订阅事件
    publisher.OnMessageSent += sub1.OnEventHandler;
    publisher.OnMessageSent += sub2.OnEventHandler;

    publisher.SendMessage("你好,C#!");

    // 取消订阅
    publisher.OnMessageSent -= sub1.OnEventHandler;
    publisher.SendMessage("再次发送消息。");
}

}
“`

3.4 LINQ (Language Integrated Query)

LINQ 允许你使用类似 SQL 的语法在 C# 代码中查询各种数据源(如集合、数据库、XML)。

“`csharp
using System.Linq; // 引入 LINQ 命名空间

class Program
{
static void Main(string[] args)
{
List numbers = new List { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    // 使用 LINQ 查询偶数
    var evenNumbers = from num in numbers
                      where num % 2 == 0
                      orderby num descending
                      select num;

    Console.WriteLine("偶数 (降序):");
    foreach (var num in evenNumbers)
    {
        Console.Write($"{num} ");
    }
    Console.WriteLine();

    // LINQ 方法语法
    var oddNumbers = numbers.Where(num => num % 2 != 0).ToList();
    Console.WriteLine("奇数:");
    foreach (var num in oddNumbers)
    {
        Console.Write($"{num} ");
    }
    Console.WriteLine();
}

}
“`

3.5 异步编程 (Asynchronous Programming)

使用 asyncawait 关键字可以编写非阻塞代码,提高应用程序的响应性,尤其在进行 I/O 操作(如网络请求、文件读写)时非常有用。

“`csharp
using System.Threading.Tasks; // 引入 Task 命名空间

class Program
{
static async Task Main(string[] args) // Main 方法可以是 async Task
{
Console.WriteLine(“主线程开始…”);
await PerformLongRunningTask(); // 调用异步方法并等待其完成
Console.WriteLine(“主线程结束。”);
}

static async Task PerformLongRunningTask()
{
    Console.WriteLine("耗时任务开始...");
    await Task.Delay(3000); // 模拟一个耗时 3 秒的操作
    Console.WriteLine("耗时任务完成。");
}

}
“`

第四部分:C# 进阶实践与生态

4.1 .NET Core / ASP.NET Core

  • .NET Core: 跨平台、高性能、开源的 .NET 版本。
  • ASP.NET Core: 用于构建现代、云就绪的 Web UI 和 Web API 的跨平台框架。理解 MVC (Model-View-Controller) 或 Razor Pages 模式是关键。

4.2 实体框架 Core (EF Core)

EF Core 是 .NET 的对象关系映射 (ORM) 框架,允许你使用 C# 对象来操作数据库,而无需编写大量的 SQL 代码。

4.3 单元测试

编写单元测试是保证代码质量的重要实践。C# 中常用的测试框架有 NUnit, xUnit, MSTest。

4.4 依赖注入 (Dependency Injection – DI)

DI 是一种设计模式,用于管理类之间的依赖关系,提高代码的模块化、可测试性和可维护性。在 ASP.NET Core 等框架中广泛使用。

4.5 设计模式

学习常见的设计模式(如单例、工厂、观察者、策略等)将帮助你编写更健壮、可扩展的代码。

4.6 版本控制 (Git)

熟练使用 Git 进行版本控制是现代软件开发的基础。

总结

C# 是一门功能强大、应用广泛的语言。从基础语法到面向对象,再到泛型、LINQ、异步编程等高级特性,C# 提供了一整套工具和框架来帮助开发者构建各种复杂的应用程序。

要精通 C#,不仅仅是学习语法,更重要的是:
1. 实践: 多写代码,通过项目巩固所学知识。
2. 阅读: 阅读优秀的 C# 开源项目代码,学习最佳实践。
3. 理解原理: 深入理解 .NET 运行时、垃圾回收、内存管理等底层机制。
4. 持续学习: C# 和 .NET 平台发展迅速,保持学习新技术和框架的习惯。

从“Hello, World!”开始,一步一个脚印,你将能够驾驭 C#,成为一名优秀的软件工程师!


滚动至顶部