掌握C#编程:30个实用小程序示例

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:C#是一种现代面向对象编程语言,广泛应用于多个领域。本资源集包含30个C#小程序示例,涵盖基础语法、数据类型、函数方法、类与对象、集合与数组、异常处理、LINQ查询、文件操作、多线程、事件与委托、GUI编程、.NET框架和异步编程等内容。这些示例旨在为初学者和经验丰富的开发者提供实践机会,帮助他们掌握C#编程基础和解决实际问题的能力。

1. C#基础语法与数据类型

在编程的世界中,C#(C Sharp)以其优雅的语法和强大的功能,成为了开发者的优选语言之一。本章,我们将从基础开始,探讨C#的关键语法和数据类型。

首先,我们要熟悉C#中的关键字,如 class namespace if 等,它们是构成C#程序的基本元素。然后,我们将探讨如何使用标识符来命名变量、方法和类。标识符的选择不仅要遵循C#的命名规则,更需要有助于代码的可读性和可维护性。

接下来,数据类型作为编程的核心,我们将详细介绍C#中的数值类型、布尔类型、字符类型和字符串类型。我们会讨论它们的特性和使用场景,并演示如何声明和初始化变量。

此外,本章还包括了如何在C#程序中使用数组和集合,以及如何高效地操作这些数据结构。你将学习到数组的声明、初始化和遍历,以及集合类如List和Dictionary的使用方法。

通过本章的学习,你将掌握C#编程的基础知识,为深入学习后续章节打下坚实的基础。

// 示例代码:变量声明和使用
int number = 42; // 声明并初始化一个整型变量
string name = "C# Programming"; // 声明并初始化一个字符串变量
bool isFun = true; // 声明并初始化一个布尔型变量

// 输出变量值
Console.WriteLine($"The number is {number}.");
Console.WriteLine($"Is programming fun? {isFun}.");
Console.WriteLine($"I love {name}!");

在上述代码中,我们声明了三种不同类型的变量,并使用 Console.WriteLine 方法输出了它们的值。这只是C#语法和数据类型的一个非常简单的入门示例。随着章节的深入,我们将逐步揭开C#的更多精彩特性。

2. C#函数与方法示例

函数和方法概念

在C#中,函数(Function)和方法(Method)通常可以互换使用。它们代表程序中的一段代码块,可以执行特定的任务,并且可以有输入参数和返回值。函数是面向过程的编程的一部分,而方法则更多地与面向对象编程联系在一起。在C#中,所有的函数都是类的一部分,因此更准确地说是方法。

定义方法

方法的定义从返回类型开始,然后是方法名、括号内的参数列表(如果有的话),最后是方法体。下面是一个简单方法的定义示例:

public int Add(int a, int b) // 返回类型为int,方法名为Add,有两个int类型的参数
{
    return a + b; // 返回两个参数的和
}

在这个例子中, Add 方法有返回类型 int ,这意味着它会返回一个整数值。方法名 Add 后跟着一对括号,括号中定义了两个名为 a b 的整数类型参数。方法体包含了实现加法逻辑的单个语句。

参数传递

C#支持值类型和引用类型参数传递。值类型参数传递时,传递的是实际值的副本;而引用类型参数传递时,传递的是实际对象的引用副本,意味着对引用类型参数的修改会影响原始对象。

返回值

方法可以通过 return 语句返回值。如果方法的返回类型不是 void ,则必须包含返回语句来返回特定类型的值。在上面的 Add 方法中,我们返回了两个参数的和。

方法重载

方法重载是指在同一个类中可以存在多个同名方法,只要它们的参数类型或参数数量不同即可。方法重载为方法的使用提供了灵活性,允许根据不同的参数类型或数量调用相同名称的方法。

public int Add(int a, int b)
{
    return a + b;
}

public double Add(double a, double b)
{
    return a + b;
}

public int Add(int a, int b, int c)
{
    return a + b + c;
}

在上述代码中, Add 方法被重载了三次,每次有不同的参数类型或数量。根据传递给 Add 方法的参数类型和数量,编译器会决定调用哪个重载版本。

方法使用实例

下面是一个使用 Add 方法的实例:

int sum = Add(5, 10); // 调用第一个Add方法,sum将会是15
double doubleSum = Add(2.5, 3.7); // 调用第二个Add方法,doubleSum将会是6.2
int sum3 = Add(1, 2, 3); // 调用第三个Add方法,sum3将会是6

方法的高级特性

在C#中,方法还可以有可选参数和命名参数,这为方法调用提供了更多的灵活性。

可选参数

可以给方法参数提供默认值,调用方法时如果没有传递该参数,则会使用默认值。

public void DisplayMessage(string message, bool includeTime = true)
{
    if (includeTime)
        Console.WriteLine($"{DateTime.Now}: {message}");
    else
        Console.WriteLine(message);
}

// 调用
DisplayMessage("Hello World!"); // 不传递includeTime参数,默认为true
DisplayMessage("Hello World!", false); // 明确传递includeTime参数为false
命名参数

在调用方法时,可以使用参数名来指定值,而不需要考虑参数的顺序。

DisplayMessage(message: "Hi, what's up?", includeTime: false);

小结

本章节通过详细的说明和实例展示了C#中方法的定义和使用,包括参数传递、返回值、方法重载以及方法的高级特性如可选参数和命名参数。通过这些基础知识,可以更有效地利用方法来构建复杂的C#程序。

3. 面向对象编程:类与对象

类与对象概念

面向对象编程(OOP)是C#编程语言中的核心概念。类是OOP的基础,它是构建对象的蓝图或模板。对象是类的实例,拥有类的属性和方法。理解类与对象是构建复杂系统和应用不可或缺的一步。

类的定义与实例化

在C#中,类使用关键字 class 进行定义。它包括属性、方法、字段和事件等成员。

public class Person
{
    // 属性
    public string Name { get; set; }
    public int Age { get; set; }

    // 方法
    public void SayHello()
    {
        Console.WriteLine("Hello, my name is " + Name);
    }

    // 构造函数
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
}
  • Name Age 是公共属性,可以被外部访问和修改。
  • SayHello 是一个方法,实现了一个行为。
  • Person(string name, int age) 是一个构造函数,用于创建对象时初始化。

对象的创建和使用

在创建类的对象时,我们通常使用 new 关键字:

Person person = new Person("Alice", 30);
person.SayHello();
  • person Person 类的一个实例。
  • 使用 person.SayHello(); 调用实例方法,执行打印操作。

类的继承

继承是面向对象编程中的一个关键特性。它允许创建类的层次结构,其中派生类继承基类的字段和方法。

public class Employee : Person
{
    public string Department { get; set; }

    public Employee(string name, int age, string department) : base(name, age)
    {
        Department = department;
    }

    public void SayDepartment()
    {
        Console.WriteLine("I work in the " + Department);
    }
}
  • Employee 类继承了 Person 类的所有成员,并添加了 Department 属性和 SayDepartment 方法。

多态

多态允许我们使用基类类型的引用来指向派生类的对象,并调用合适的方法实现。在C#中,多态是通过虚方法和重写实现的。

public class Vehicle
{
    public virtual void Start()
    {
        Console.WriteLine("Vehicle is starting");
    }
}

public class Car : Vehicle
{
    public override void Start()
    {
        Console.WriteLine("Car is starting");
    }
}

// 使用
Vehicle vehicle = new Car();
vehicle.Start(); // 输出: Car is starting
  • Car 类重写了 Vehicle 类的 Start 方法。

封装

封装是隐藏对象内部的复杂性,仅暴露接口的方法。在C#中,通过使用访问修饰符实现封装。

public class BankAccount
{
    private decimal balance;

    public decimal GetBalance()
    {
        return balance;
    }

    public void Deposit(decimal amount)
    {
        if (amount > 0)
        {
            balance += amount;
        }
    }
}
  • balance 是私有字段,只能在类内部访问。
  • GetBalance Deposit 是公开方法,外部通过这些方法操作私有字段。

类与对象的高级应用

静态成员

静态成员属于类本身,而非类的任何实例。静态字段和静态方法通常用于创建不需要实例化类的对象即可使用的功能。

public class Utility
{
    public static void Log(string message)
    {
        Console.WriteLine("Log: " + message);
    }
}

// 使用
Utility.Log("Application started");
  • Log 方法是静态的,可以不需要 Utility 类的实例即可调用。

抽象类与接口

抽象类和接口是实现抽象级别的OOP概念。抽象类使用 abstract 关键字定义,不能实例化。它可以包含抽象方法和非抽象方法。

public abstract class Shape
{
    public abstract void Draw();
}

接口使用 interface 关键字定义,它声明了类必须实现的方法,但不提供方法实现。

public interface IRenderer
{
    void Render();
}

对象的比较

对象比较可以是值比较或引用比较。值比较通常比较对象的内容,而引用比较比较对象的内存地址。

public static bool AreEqual(Person p1, Person p2)
{
    if (ReferenceEquals(p1, p2)) return true;
    if (p1 is null || p2 is null) return false;
    return p1.Name == p2.Name && p1.Age == p2.Age;
}
  • ReferenceEquals 用于引用比较。
  • Equals 方法和运算符 == 可以被重载以支持值比较。

对象的序列化

对象的序列化是将对象的状态保存到存储介质中,或者通过网络传输的过程。C#提供了 System.Runtime.Serialization 命名空间,它支持对象的序列化和反序列化。

[Serializable]
public class User
{
    public string Name { get; set; }
    public int Age { get; set; }
}

// 序列化示例
User user = new User { Name = "John", Age = 30 };
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("user.data", FileMode.Create);
formatter.Serialize(stream, user);
stream.Close();
  • [Serializable] 属性标记允许对象被序列化。
  • 使用 BinaryFormatter 类对 User 对象进行序列化操作。

总结

类和对象是构成面向对象编程的基础。本章深入探讨了类的定义、对象的创建、继承、多态、封装等核心概念,并通过实例展示了如何利用这些特性来实现复杂的功能和解决方案。通过静态成员、抽象类、接口以及对象的比较和序列化等高级技术,C#程序员可以编写出结构清晰、易于维护和扩展的应用程序。下一章将详细介绍C#中的集合与数组应用,探索更多数据管理的高效工具和方法。

4. C#集合与数组应用

4.1 集合类型简介

在C#中,集合是存储一组元素的容器,这些元素可以是任意数据类型。集合是编程中常用的数据结构,用于管理数据集合。C# 提供了丰富的集合类,主要分为接口和类两大类。接口集合如 IEnumerable<T> ICollection<T> IList<T> 等,而类集合如 List<T> Dictionary<TKey, TValue> HashSet<T> 等。

4.1.1 列表(List)

列表是最常用的集合类型之一。 List<T> 类是一个泛型集合,允许动态地添加和移除元素,它实现了 IList<T> 接口。列表元素可以通过索引直接访问。

使用列表
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
        numbers.Add(6); // 添加元素到列表末尾
        numbers.Insert(2, 25); // 在指定索引处插入元素
        numbers.RemoveAt(0); // 移除指定索引处的元素
        Console.WriteLine(numbers.Contains(25)); // 检查列表是否包含指定元素
        foreach (int number in numbers)
        {
            Console.WriteLine(number);
        }
    }
}

4.1.2 字典(Dictionary)

字典是一种存储键值对的数据结构。在C#中, Dictionary<TKey, TValue> 类实现了 IDictionary<TKey, TValue> 接口。字典提供了通过键快速访问值的能力。

使用字典
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        Dictionary<string, int> ages = new Dictionary<string, int>
        {
            {"Alice", 24},
            {"Bob", 27}
        };
        ages.Add("Charlie", 32); // 添加新的键值对
        if (ages.TryGetValue("Alice", out int aliceAge))
        {
            Console.WriteLine($"Alice's age is {aliceAge}.");
        }
        foreach (KeyValuePair<string, int> pair in ages)
        {
            Console.WriteLine($"{pair.Key} is {pair.Value} years old.");
        }
    }
}

4.1.3 队列(Queue)

队列是一种先进先出(FIFO)的数据结构。 Queue<T> 类实现了 IEnumerable<T> ICollection ISerializable 接口。

使用队列
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        Queue<string> queue = new Queue<string>();
        queue.Enqueue("First"); // 入队操作
        queue.Enqueue("Second");
        queue.Enqueue("Third");
        Console.WriteLine(queue.Dequeue()); // 出队操作,移除并返回队列的前端元素
        foreach (string s in queue)
        {
            Console.WriteLine($"Queue: {s}");
        }
    }
}

4.2 数组

数组是一种数据结构,用于存储固定大小且类型相同的元素序列。在C#中,数组是引用类型,可以通过索引访问数组元素。

4.2.1 声明和初始化数组

数组的声明包括指定数组元素的类型和数组变量的名字,以及一对方括号来表示数组的维度。

string[] names = new string[3]; // 声明一个包含3个字符串的数组
names[0] = "Alice";
names[1] = "Bob";
names[2] = "Charlie";

4.2.2 多维数组

多维数组用于存储多维度的数据结构。二维数组是最常见的多维数组类型。

int[,] matrix = new int[3, 2];
matrix[0, 0] = 1;
matrix[0, 1] = 2;
matrix[1, 0] = 3;
matrix[1, 1] = 4;
matrix[2, 0] = 5;
matrix[2, 1] = 6;

4.3 集合与数组的高级操作

4.3.1 LINQ查询

LINQ(语言集成查询)提供了一种查询数据源(包括数组和集合)的简洁方法。

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
        var evenNumbers = from number in numbers
                          where number % 2 == 0
                          select number;
        foreach (int number in evenNumbers)
        {
            Console.WriteLine(number);
        }
    }
}

4.3.2 集合的排序和过滤

排序和过滤是处理数据时常见的操作。

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 5, 2, 9, 1, 6 };
        var sortedNumbers = numbers.OrderBy(n => n); // 排序
        var evenNumbers = numbers.Where(n => n % 2 == 0).ToList(); // 过滤偶数
        foreach (int number in sortedNumbers)
        {
            Console.WriteLine(number);
        }
        foreach (int number in evenNumbers)
        {
            Console.WriteLine(number);
        }
    }
}

4.4 性能优化与最佳实践

在使用集合与数组时,性能优化和最佳实践对提高效率和可读性至关重要。

4.4.1 使用泛型集合

使用泛型集合可以提高代码的类型安全性和性能,因为泛型减少了不必要的装箱和拆箱操作。

4.4.2 避免不必要的集合转换

频繁地转换集合类型可能会导致性能下降。应尽量在创建集合时就选择合适的类型。

4.4.3 利用集合的内置方法

大多数集合类提供了丰富的方法来操作数据,例如 AddRange RemoveAll FindAll 等。使用这些内置方法可以提高代码的可读性和效率。

在本章中,我们详细了解了C#中的集合与数组,包括它们的定义、使用方式和性能优化的策略。通过实例演示了如何高效处理和操作数据集合,这些知识对于构建性能优良的应用程序至关重要。随着对集合与数组的深入理解和实践,您将能够灵活应对数据管理的各种挑战。

5. 异常处理机制

异常处理是确保程序稳定运行和良好用户体验的关键技术。C#中的异常处理机制能够帮助开发者捕捉程序运行时的错误情况,防止程序因未处理的错误而意外终止。在这一章节中,我们将深入了解C#异常处理的细节,并通过实际代码示例来演示如何在日常开发中应用这些技术。

5.1 基本的异常处理结构

C#中的异常处理是通过使用 try catch finally throw 关键字来实现的。 try 块包含了可能抛出异常的代码。如果在 try 块中的代码执行过程中发生异常,那么异常会被传递到最近的 catch 块中。 finally 块则无论是否发生异常都会执行,通常用于资源的清理和释放。

下面是一个简单的异常处理结构示例:

try
{
    // 尝试执行的代码
    int[] numbers = new int[5];
    Console.WriteLine(numbers[10]); // 这里会抛出一个IndexOutOfRangeException
}
catch (Exception ex)
{
    // 捕获异常并进行处理
    Console.WriteLine("发生了一个错误: " + ex.Message);
}
finally
{
    // 最终块,无论是否发生异常都会执行
    Console.WriteLine("这段代码总是会执行。");
}

5.2 自定义异常

在某些情况下,我们需要定义自己的异常类型,以便提供更具体的错误信息。通过继承 Exception 类来创建自定义异常,可以让异常处理过程更加具有可读性和维护性。

// 自定义异常类
public class CustomException : Exception
{
    public CustomException(string message) : base(message) {}
}

// 使用自定义异常
try
{
    throw new CustomException("这是一个自定义异常。");
}
catch (CustomException ex)
{
    Console.WriteLine("捕获到自定义异常: " + ex.Message);
}

5.3 异常的抛出和捕获

异常的抛出是通过 throw 关键字实现的。在C#中,可以抛出任何继承自 System.Exception 的类型。有时候,我们可能需要根据特定条件抛出异常,这时可以在 catch 块内部使用 throw 来重新抛出异常。

// 使用条件语句抛出异常
try
{
    int result = Calculate(10, 0); // Calculate函数可能会抛出异常
}
catch (DivideByZeroException ex)
{
    Console.WriteLine("捕获到除零异常。");
    throw; // 重新抛出当前捕获的异常
}

// 计算函数
public int Calculate(int x, int y)
{
    if (y == 0)
        throw new DivideByZeroException();
    return x / y;
}

5.4 处理多个异常

当一段代码有可能抛出不同类型的多个异常时,可以使用多个 catch 块来分别处理。需要注意的是, catch 块的顺序很重要,因为C#会从上至下检查 catch 块,一旦某个块匹配,其余的将不会被执行。

try
{
    // 可能抛出不同异常的代码
    int result = int.Parse(Console.ReadLine());
}
catch (FormatException ex)
{
    Console.WriteLine("输入格式不正确。");
}
catch (OverflowException ex)
{
    Console.WriteLine("数字超出范围。");
}
catch (Exception ex)
{
    // 默认处理所有其他异常
    Console.WriteLine("发生了一个未知错误。");
}

在上述的五个示例中,我们介绍了C#异常处理的不同方面,包括基本的 try-catch-finally 结构,自定义异常的创建与使用,异常的抛出与捕获,以及处理多个异常的情况。理解这些概念对于编写健壮和可靠的C#应用程序至关重要。

在实践中,合理使用异常处理可以提高程序的可维护性和用户的体验。例如,在处理用户输入时,适当的异常处理可以保证程序不会因为用户的错误操作而崩溃,并且能够给出友好的错误信息。在下一节中,我们将探讨如何利用LINQ技术进行高效的数据查询操作。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:C#是一种现代面向对象编程语言,广泛应用于多个领域。本资源集包含30个C#小程序示例,涵盖基础语法、数据类型、函数方法、类与对象、集合与数组、异常处理、LINQ查询、文件操作、多线程、事件与委托、GUI编程、.NET框架和异步编程等内容。这些示例旨在为初学者和经验丰富的开发者提供实践机会,帮助他们掌握C#编程基础和解决实际问题的能力。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

第1章 C#编程基础  实例1 Hello C#!  实例2 HeyGuy  实例3 预定义类型  实例4 类型转换  实例5 选择语句  实例6 循环语句  实例7 跳转语句  实例8 数组  实例9 枚举与结构类型  实例10 类  实例11 位运算  实例12 操作符重载  实例13 虚方法  实例14 委托  实例15 属性  实例16 异常处理  实例17 链表  实例18 回文数  实例19 汉诺塔  实例20 冒泡排序  实例21 插入排序  小结 第2章 界面编程  实例22 Hello Form  实例23 主菜单  实例24 上下文菜单  实例25 工具栏  实例26 状态栏  实例27 进度条  实例28 滑块控件  实例29 单选框和复选框  实例30 列表框和组合框  实例31 列表视图  实例32 树视图  实例33 Timer控件  实例34 Splitter控件  实例35 时钟控件和日历控件  实例36 MDI窗口  实例37 窗体继承  实例38 自制控件  实例39 使用自制控件  实例40 模式与非模式  实例41 会跑的按钮  实例42 绘制背景  实例43 可调窗口  实例44 托动窗体  实例45 电子便条  实例46 计算器界面设计  实例47 计算器功能实现  实例48 小闹钟  小结 第3章 图形与图像处理  实例49 简单画图  实例50 使用OnPaint绘制图形  实例51 绘制贝赛尔曲线  实例52 显示图像  实例53 消除图片背景  实例54 底片滤镜  实例55 浮雕效果  实例56 显示字体  实例57 特效字  实例58 旋转图片  实例59 打印  小结 第4章 线程 第5章 文件处理和系统操作 第6章 数据库编程 第7章 网络编程 第8章 Web应用程序的开发 第9章 多媒体 第10章 安全性 第11章 设计模式 第12章 杂例
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值