赞
踩
无论你是编程新手,还是想要深化.NET技能的开发者,本文都将为你提供一条清晰的学习路径,从C#基础到高级特性,每一站都配有详尽解析和实用示例,旨在帮助你建立坚实的知识体系,并激发你对C#及.NET生态的热情。
目录
C#(发音为“See Sharp”)由微软公司精心打造,是一种现代化的面向对象编程语言。它在.NET平台上运行,旨在提供高效、类型安全的开发体验,广泛应用于Windows桌面应用、Web服务、游戏开发(Unity尤为青睐)、以及跨平台解决方案。让我们一起揭开C#的面纱,逐步掌握其精髓。
- using System;
-
- namespace HelloWorld
- {
- class Program
- {
- static void Main(string[] args)
- {
- Console.WriteLine("你好,C#的世界!");
- }
- }
- }
这行简单的输出,标志着你的C#旅程正式启航。
在C#编程语言中,变量、数据类型和控制流是构建程序的基础元素。下面我将详细讲解这些概念,并提供一些示例代码来帮助理解。
变量是存储数据的基本单元。在C#中,变量必须先声明后使用,并且需要指定其数据类型。
- int age = 25; // 声明一个整数型变量age并赋值为25
- string name = "Alice"; // 声明一个字符串型变量name并赋值为"Alice"
- double height = 1.75; // 声明一个双精度浮点型变量height并赋值为1.75
C#支持多种数据类型,包括基本数据类型和复合数据类型。基本数据类型包括整数类型(如int
)、浮点类型(如double
)、字符类型(如char
)和布尔类型(如bool
)。
- int number = 10; // 整数类型
- double pi = 3.14159; // 双精度浮点类型
- char letter = 'A'; // 字符类型
- bool isTrue = true; // 布尔类型
控制流语句用于控制程序的执行流程,包括条件判断和循环操作。常见的控制流语句有if
、for
、while
和switch
等。
4)条件判断(if语句)
if
语句用于根据条件执行不同的代码块。
- int x = 10;
- if (x > 5)
- {
- Console.WriteLine("x is greater than 5");
- }
- else
- {
- Console.WriteLine("x is not greater than 5");
- }
for
语句用于重复执行一段代码,直到满足特定条件为止。
- for (int i = 0; i < 5; i++)
- {
- Console.WriteLine("Iteration " + i);
- }
while
语句用于在条件为真时重复执行一段代码。
- int count = 0;
- while (count < 5)
- {
- Console.WriteLine("Count is " + count);
- count++;
- }
switch
语句用于根据变量的值执行不同的代码块。
- int day = 3;
- switch (day)
- {
- case 1:
- Console.WriteLine("Monday");
- break;
- case 2:
- Console.WriteLine("Tuesday");
- break;
- case 3:
- Console.WriteLine("Wednesday");
- break;
- default:
- Console.WriteLine("Other day");
- break;
- }
类是用户定义的数据类型,它包含数据成员(字段)和函数成员(方法、属性、事件等)。类定义了对象的结构和行为。
示例:
- public class Person
- {
- // 字段
- private string name;
- private int age;
-
- // 构造函数
- public Person(string name, int age)
- {
- this.name = name;
- this.age = age;
- }
-
- // 属性
- public string Name
- {
- get { return name; }
- set { name = value; }
- }
-
- public int Age
- {
- get { return age; }
- set { age = value; }
- }
-
- // 方法
- public void SayHello()
- {
- Console.WriteLine($"Hello, my name is {name} and I am {age} years old.");
- }
- }
对象是类的实例,通过类创建对象的过程称为实例化。对象可以访问类中定义的字段、属性和方法。
示例:
- class Program
- {
- static void Main()
- {
- // 创建对象
- Person person = new Person("Alice", 30);
-
- // 访问属性
- Console.WriteLine(person.Name); // 输出: Alice
- Console.WriteLine(person.Age); // 输出: 30
-
- // 调用方法
- person.SayHello(); // 输出: Hello, my name is Alice and I am 30 years old.
-
- // 修改属性
- person.Name = "Bob";
- person.Age = 25;
-
- // 再次调用方法
- person.SayHello(); // 输出: Hello, my name is Bob and I am 25 years old.
- }
- }
构造函数是类的一种特殊方法,用于初始化对象。构造函数与类同名,没有返回类型。
示例:
- public class Person
- {
- private string name;
- private int age;
-
- // 构造函数
- public Person(string name, int age)
- {
- this.name = name;
- this.age = age;
- }
-
- // 其他成员省略...
- }
属性提供了一种访问和修改字段的机制,它包含 get 和 set 访问器。
示例:
- public class Person
- {
- private string name;
- private int age;
-
- public string Name
- {
- get { return name; }
- set { name = value; }
- }
-
- public int Age
- {
- get { return age; }
- set { age = value; }
- }
-
- // 其他成员省略...
- }
方法是类中定义的函数,用于执行特定的操作。
示例:
- public class Person
- {
- private string name;
- private int age;
-
- public void SayHello()
- {
- Console.WriteLine($"Hello, my name is {name} and I am {age} years old.");
- }
-
- // 其他成员省略...
- }
继承是面向对象编程的一个重要特性,它允许一个类继承另一个类的字段和方法。
示例:
- public class Student : Person
- {
- private string studentId;
-
- public Student(string name, int age, string studentId) : base(name, age)
- {
- this.studentId = studentId;
- }
-
- public string StudentId
- {
- get { return studentId; }
- set { studentId = value; }
- }
-
- public void Study()
- {
- Console.WriteLine($"{Name} with student ID {studentId} is studying.");
- }
- }
-
- class Program
- {
- static void Main()
- {
- Student student = new Student("Alice", 20, "12345");
- student.SayHello(); // 输出: Hello, my name is Alice and I am 20 years old.
- student.Study(); // 输出: Alice with student ID 12345 is studying.
- }
- }
封装是将数据和操作数据的方法绑定在一起,并隐藏对象的内部实现细节。C# 通过访问修饰符(如 private
、public
、protected
)来实现封装。
示例:
- public class Person
- {
- private string name;
- private int age;
-
- public string Name
- {
- get { return name; }
- set { name = value; }
- }
-
- public int Age
- {
- get { return age; }
- set { age = value; }
- }
-
- // 其他成员省略...
- }
通过这些示例,你可以看到 C# 中类与对象的基本概念和用法。类是对象的蓝图,而对象是类的实例。类定义了对象的结构和行为,而对象是类的具体实现。继承、封装和多态是面向对象编程的三大特性,它们在 C# 中得到了很好的支持。
C# 中的泛型和集合是两个非常重要的概念,它们极大地增强了代码的灵活性和可重用性。下面我将详细讲解这两个概念。
泛型允许你在定义类、接口、方法或委托时使用类型参数,从而使这些类型或方法可以在不指定具体类型的情况下工作。泛型提高了代码的重用性,增强了类型安全性,并减少了类型转换的需要。
示例:
- public class GenericClass<T>
- {
- private T _value;
-
- public GenericClass(T value)
- {
- _value = value;
- }
-
- public T GetValue()
- {
- return _value;
- }
- }
-
- class Program
- {
- static void Main()
- {
- GenericClass<int> intGeneric = new GenericClass<int>(10);
- Console.WriteLine(intGeneric.GetValue()); // 输出: 10
-
- GenericClass<string> stringGeneric = new GenericClass<string>("Hello");
- Console.WriteLine(stringGeneric.GetValue()); // 输出: Hello
- }
- }
示例:
- public class GenericMethod
- {
- public static void Print<T>(T value)
- {
- Console.WriteLine(value);
- }
- }
-
- class Program
- {
- static void Main()
- {
- GenericMethod.Print(10); // 输出: 10
- GenericMethod.Print("Hello"); // 输出: Hello
- }
- }
你可以通过泛型约束来限制类型参数必须满足的条件。
示例:
- public class GenericClassWithConstraint<T> where T : IComparable<T>
- {
- private T _value;
-
- public GenericClassWithConstraint(T value)
- {
- _value = value;
- }
-
- public T GetValue()
- {
- return _value;
- }
-
- public bool IsGreaterThan(T other)
- {
- return _value.CompareTo(other) > 0;
- }
- }
-
- class Program
- {
- static void Main()
- {
- GenericClassWithConstraint<int> intGeneric = new GenericClassWithConstraint<int>(10);
- Console.WriteLine(intGeneric.IsGreaterThan(5)); // 输出: True
- }
- }
C# 提供了多种集合类型,用于存储和操作一组对象。这些集合类型包括数组、列表、队列、栈、字典等。
数组是最基本的集合类型,它具有固定大小。
示例:
- int[] numbers = new int[5];
- numbers[0] = 1;
- numbers[1] = 2;
- numbers[2] = 3;
- numbers[3] = 4;
- numbers[4] = 5;
-
- foreach (int number in numbers)
- {
- Console.WriteLine(number);
- }
列表是一种动态数组,它的大小可以动态调整。
示例:
- using System.Collections.Generic;
-
- List<int> numbers = new List<int>();
- numbers.Add(1);
- numbers.Add(2);
- numbers.Add(3);
- numbers.Add(4);
- numbers.Add(5);
-
- foreach (int number in numbers)
- {
- Console.WriteLine(number);
- }
队列是一种先进先出 (FIFO) 的数据结构。
示例:
- using System.Collections.Generic;
-
- Queue<int> queue = new Queue<int>();
- queue.Enqueue(1);
- queue.Enqueue(2);
- queue.Enqueue(3);
-
- while (queue.Count > 0)
- {
- Console.WriteLine(queue.Dequeue());
- }
栈是一种后进先出 (LIFO) 的数据结构。
示例:
- using System.Collections.Generic;
-
- Stack<int> stack = new Stack<int>();
- stack.Push(1);
- stack.Push(2);
- stack.Push(3);
-
- while (stack.Count > 0)
- {
- Console.WriteLine(stack.Pop());
- }
字典是一种键值对集合,可以通过键快速查找值。
示例:
- using System.Collections.Generic;
-
- Dictionary<string, int> dictionary = new Dictionary<string, int>();
- dictionary.Add("one", 1);
- dictionary.Add("two", 2);
- dictionary.Add("three", 3);
-
- foreach (var item in dictionary)
- {
- Console.WriteLine($"{item.Key}: {item.Value}");
- }
泛型集合是 C# 中推荐的集合类型,因为它们提供了类型安全性和性能优势。
示例:
- using System.Collections.Generic;
-
- List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
- Queue<string> queue = new Queue<string>();
- queue.Enqueue("first");
- queue.Enqueue("second");
- Stack<double> stack = new Stack<double>();
- stack.Push(1.1);
- stack.Push(2.2);
- Dictionary<int, string> dictionary = new Dictionary<int, string>
- {
- { 1, "one" },
- { 2, "two" },
- { 3, "three" }
- };
-
- foreach (int number in numbers)
- {
- Console.WriteLine(number);
- }
-
- while (queue.Count > 0)
- {
- Console.WriteLine(queue.Dequeue());
- }
-
- while (stack.Count > 0)
- {
- Console.WriteLine(stack.Pop());
- }
-
- foreach (var item in dictionary)
- {
- Console.WriteLine($"{item.Key}: {item.Value}");
- }
通过这些示例,你可以看到泛型和集合在 C# 中的强大功能和灵活性。它们是现代 C# 编程中不可或缺的工具。
- try
- {
- // 尝试访问数组越界
- int[] arr = { 1, 2, 3 };
- Console.WriteLine(arr[3]);
- }
- catch (IndexOutOfRangeException ex)
- {
- Console.WriteLine("数组越界:" + ex.Message);
- }
使用try-catch
捕获并处理异常,增强程序的健壮性。
- List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
- var evenNumbers = numbers.Where(n => n % 2 == 0);
- foreach (var num in evenNumbers)
- {
- Console.WriteLine(num);
- }
Lambda表达式让代码更简洁,LINQ则提供了查询数据的强大工具集。
C# 多线程与并发编程技术是现代软件开发中的重要组成部分,它允许开发者创建高效、响应迅速的应用程序。以下是对C#中多线程与并发编程技术的详细介绍:
在C#中,线程是执行代码的基本单元。可以使用 System.Threading.Thread
类来创建和管理线程。
示例:
- using System;
- using System.Threading;
-
- class Program
- {
- static void Main()
- {
- Thread thread = new Thread(new ThreadStart(DoWork));
- thread.Start();
- Console.WriteLine("Main thread continues.");
- }
-
- static void DoWork()
- {
- Console.WriteLine("Worker thread is running.");
- }
- }
线程池是一种管理线程的机制,它可以重用线程,减少线程创建和销毁的开销。可以使用 ThreadPool
类来使用线程池。
示例:
- using System;
- using System.Threading;
-
- class Program
- {
- static void Main()
- {
- ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork));
- Console.WriteLine("Main thread continues.");
- Thread.Sleep(1000); // 等待工作线程完成
- }
-
- static void DoWork(object state)
- {
- Console.WriteLine("Worker thread from thread pool is running.");
- }
- }
任务并行库 (Task Parallel Library, TPL) 是 .NET Framework 4.0 引入的一个库,它提供了更高级别的抽象来处理并发和并行编程。
示例:
- using System;
- using System.Threading.Tasks;
-
- class Program
- {
- static void Main()
- {
- Task task = Task.Run(() => DoWork());
- Console.WriteLine("Main thread continues.");
- task.Wait(); // 等待任务完成
- }
-
- static void DoWork()
- {
- Console.WriteLine("Task is running.");
- }
- }
TPL 还提供了并行循环的机制,如 Parallel.For
和 Parallel.ForEach
,它们可以自动并行化循环操作。
示例:
- using System;
- using System.Threading.Tasks;
-
- class Program
- {
- static void Main()
- {
- Parallel.For(0, 10, i =>
- {
- Console.WriteLine($"Task {i} is running.");
- });
- }
- }
异步编程模型 (async/await) 是 C# 5.0 引入的一种编程模式,它使得异步编程更加简单和直观。
示例:
- using System;
- using System.Threading.Tasks;
-
- class Program
- {
- static async Task Main()
- {
- await DoWorkAsync();
- Console.WriteLine("Main thread continues.");
- }
-
- static async Task DoWorkAsync()
- {
- await Task.Delay(1000); // 模拟异步操作
- Console.WriteLine("Async task is completed.");
- }
- }
.NET 提供了一些并发集合类,如 ConcurrentQueue
、ConcurrentStack
和 ConcurrentDictionary
,它们可以在多线程环境下安全地进行操作。
示例:
- using System;
- using System.Collections.Concurrent;
- using System.Threading.Tasks;
-
- class Program
- {
- static void Main()
- {
- ConcurrentQueue<int> queue = new ConcurrentQueue<int>();
-
- Task producer = Task.Run(() =>
- {
- for (int i = 0; i < 10; i++)
- {
- queue.Enqueue(i);
- Console.WriteLine($"Enqueued {i}");
- }
- });
-
- Task consumer = Task.Run(() =>
- {
- int result;
- while (queue.TryDequeue(out result))
- {
- Console.WriteLine($"Dequeued {result}");
- }
- });
-
- Task.WaitAll(producer, consumer);
- }
- }
原子操作是不可分割的操作,可以确保在多线程环境下操作的原子性。Interlocked
类提供了一些原子操作方法。
示例:
- using System;
- using System.Threading;
-
- class Program
- {
- static int counter = 0;
-
- static void Main()
- {
- for (int i = 0; i < 10; i++)
- {
- new Thread(IncrementCounter).Start();
- }
- }
-
- static void IncrementCounter()
- {
- int newValue = Interlocked.Increment(ref counter);
- Console.WriteLine($"Counter: {newValue}");
- }
- }
通过这些技术和工具,C# 开发者可以有效地处理多线程和并发编程,创建高性能、高并发的应用程序。
- public delegate void MessageHandler(string msg);
- public class Publisher
- {
- public event MessageHandler NewMessage;
-
- public void Publish(string message)
- {
- NewMessage?.Invoke(message);
- }
- }
委托机制允许你将方法作为参数传递,事件则是基于委托的通信方式,增强了组件之间的解耦。
Monitor
、Semaphore
等,提供了更细致的并发控制手段。 1)lock
关键字lock
关键字用于确保在同一时刻只有一个线程可以进入代码的临界区。
- using System;
- using System.Threading;
-
- class Counter
- {
- private int count = 0;
- private readonly object lockObject = new object();
-
- public void Increment()
- {
- lock (lockObject)
- {
- count++;
- Console.WriteLine($"Count: {count}");
- }
- }
- }
-
- class Program
- {
- static void Main()
- {
- var counter = new Counter();
- for (int i = 0; i < 10; i++)
- {
- new Thread(counter.Increment).Start();
- }
- }
- }
在这个示例中,lock
关键字确保了 count
变量的自增操作是线程安全的。
Monitor
类Monitor
类提供了与 lock
关键字类似的功能,但提供了更多的控制选项,如 Wait
和 Pulse
方法。
- using System;
- using System.Threading;
-
- class CounterWithMonitor
- {
- private int count = 0;
- private readonly object lockObject = new object();
-
- public void Increment()
- {
- Monitor.Enter(lockObject);
- try
- {
- count++;
- Console.WriteLine($"Count: {count}");
- }
- finally
- {
- Monitor.Exit(lockObject);
- }
- }
- }
-
- class Program
- {
- static void Main()
- {
- var counter = new CounterWithMonitor();
- for (int i = 0; i < 10; i++)
- {
- new Thread(counter.Increment).Start();
- }
- }
- }
在这个示例中,Monitor.Enter
和 Monitor.Exit
方法用于确保 count
变量的自增操作是线程安全的。
Semaphore
类Semaphore
类用于控制对一个或多个共享资源的并发访问。它可以限制同时访问资源的线程数量。
- using System;
- using System.Threading;
-
- class SemaphoreExample
- {
- private static Semaphore semaphore = new Semaphore(2, 2); // 允许2个线程同时访问
-
- public void AccessResource(int threadId)
- {
- semaphore.WaitOne();
- try
- {
- Console.WriteLine($"Thread {threadId} is accessing the resource.");
- Thread.Sleep(1000); // 模拟资源访问时间
- }
- finally
- {
- Console.WriteLine($"Thread {threadId} is releasing the resource.");
- semaphore.Release();
- }
- }
- }
-
- class Program
- {
- static void Main()
- {
- var semaphoreExample = new SemaphoreExample();
- for (int i = 0; i < 5; i++)
- {
- int threadId = i;
- new Thread(() => semaphoreExample.AccessResource(threadId)).Start();
- }
- }
- }
在这个示例中,Semaphore
类限制了同时访问资源的线程数量为2个。
通过这些示例,你可以看到如何在C#中使用不同的同步工具来确保线程安全。选择合适的同步工具取决于具体的应用场景和需求。
选择一个小型项目,如简单的图书管理系统、天气查询应用等,动手实践。从需求分析到编码实现,再到调试部署,每一步都是学习成长的机会。记得利用学到的所有知识:OOP设计、泛型集合、异常处理、多线程等,让理论在实践中开花结果。
C#及其.NET平台是一个广阔且不断演进的技术宇宙。本文仅是入门与进阶的起点,鼓励你持续探索,如C# 10的新特性、Blazor WebAssembly、.NET MAUI跨平台开发等。参加社区讨论,阅读官方文档,不断实践,你将会发现C#不仅仅是一种语言,它是一种强大的工具,助你创造无限可能。现在,带着这份指南,开启你的C#编程征途吧!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。