第九章:C# 常量

本文介绍了C#中常量的概念,包括和关键字的区别,以及静态常量的使用。强调了常量命名约定,并讨论了常量在性能、不变性、线程安全以及枚举中的应用。提供了思考问题和练习题,帮助读者深入理解和应用C#中的常量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

常量是编程中用于表示不可更改值的一种变量。在C#中,常量通过constreadonly关键字来定义。理解如何正确使用常量,有助于编写更健壮和可维护的代码。

1. const 常量

const关键字用于定义编译时常量。const常量在声明时必须初始化,并且在程序运行期间不能更改。const常量通常用于定义那些在程序执行期间保持不变的值。

示例:

class Program
{
    const double Pi = 3.14159;
    const int DaysInWeek = 7;

    static void Main(string[] args)
    {
        Console.WriteLine($"Value of Pi: {Pi}");
        Console.WriteLine($"Days in a week: {DaysInWeek}");
    }
}

在这个示例中,我们定义了两个const常量PiDaysInWeek,并在Main方法中输出它们的值。尝试在程序中更改这些常量的值会导致编译错误。

2. readonly 常量

readonly关键字用于定义运行时常量。readonly常量可以在声明时或在构造函数中初始化,但在其他任何地方都不能更改。readonly常量适用于那些在运行时才能确定的常量值。

示例:

class Program
{
    readonly int year;

    public Program(int year)
    {
        this.year = year;
    }

    void DisplayYear()
    {
        Console.WriteLine($"Year: {year}");
    }

    static void Main(string[] args)
    {
        Program program = new Program(2024);
        program.DisplayYear();
    }
}

在这个示例中,我们定义了一个readonly常量year,并在构造函数中对其进行初始化。尝试在其他地方更改这个常量的值会导致编译错误。

3. constreadonly 的区别
  • 初始化时间const常量在编译时初始化,而readonly常量可以在运行时初始化。
  • 赋值位置const常量只能在声明时赋值,而readonly常量可以在声明时或构造函数中赋值。
  • 应用场景const常量适用于那些在编译时就已知且不会改变的值,如数学常数。readonly常量适用于那些在运行时确定的值,如从配置文件读取的配置项。

示例:

class Constants
{
    const double Pi = 3.14159;
    readonly int year;

    public Constants(int year)
    {
        this.year = year;
    }

    void DisplayValues()
    {
        Console.WriteLine($"Pi: {Pi}");
        Console.WriteLine($"Year: {year}");
    }

    static void Main(string[] args)
    {
        Constants constants = new Constants(2024);
        constants.DisplayValues();
    }
}

在这个示例中,我们展示了如何使用constreadonly定义常量,并分别对它们进行初始化和使用。

4. 静态常量

静态常量是指通过static关键字修饰的常量。静态常量属于类本身,而不是类的实例。静态常量可以是const也可以是readonly

示例:

class Constants
{
    public const double Pi = 3.14159;
    public static readonly int Year;

    static Constants()
    {
        Year = DateTime.Now.Year;
    }

    static void Main(string[] args)
    {
        Console.WriteLine($"Pi: {Pi}");
        Console.WriteLine($"Year: {Year}");
    }
}

在这个示例中,我们定义了一个const静态常量Pi和一个readonly静态常量YearYear常量在静态构造函数中进行初始化。

5. 常量的命名约定

常量的命名通常使用全大写字母,并用下划线分隔单词。这是为了在代码中显而易见地标识常量。

示例:

class Program
{
    const double PI = 3.14159;
    const int DAYS_IN_WEEK = 7;

    static void Main(string[] args)
    {
        Console.WriteLine($"Value of PI: {PI}");
        Console.WriteLine($"Days in a week: {DAYS_IN_WEEK}");
    }
}

在这个示例中,我们使用全大写字母和下划线来命名常量PIDAYS_IN_WEEK,以便在代码中清楚地识别它们。

结束语

掌握C#中常量的定义和使用方法,包括constreadonly常量的区别、静态常量的使用、以及常量的命名约定。

思考

1. constreadonly 的用例和最佳实践

最佳实践

  • 使用const来定义那些真正不会变化的常量,例如数学常数、固定配置值等。
  • 使用readonly来定义那些需要在运行时初始化的常量,例如基于当前时间、配置文件或其他外部输入的值。

示例

class Configuration
{
    public const string DefaultFilePath = "/etc/config";
    public readonly string ConfigFilePath;

    public Configuration(string configFilePath)
    {
        ConfigFilePath = configFilePath ?? DefaultFilePath;
    }
}

在这个示例中,DefaultFilePath是一个编译时常量,而ConfigFilePath是一个运行时常量,可以根据构造函数的输入进行初始化。

2. 静态常量与实例常量

静态常量

  • 静态常量适用于那些在所有实例中共享的值,例如全局配置、应用程序级别的常量等。
  • 静态常量可以是const也可以是readonly,取决于是否需要在运行时初始化。

实例常量

  • 实例常量适用于那些每个对象实例可以有不同值的常量,例如对象特定的配置值。
  • 实例常量通常使用readonly,以便在构造函数中初始化。

示例

class Constants
{
    public const double Pi = 3.14159; // 静态常量
    public static readonly string ApplicationName = "MyApp"; // 静态只读常量
    public readonly string InstanceName; // 实例只读常量

    public Constants(string instanceName)
    {
        InstanceName = instanceName;
    }
}

在这个示例中,PiApplicationName是静态常量,而InstanceName是实例常量。

3. 常量的性能考虑

性能优化

  • const常量在编译时确定,因此在使用时性能优异,不会有任何运行时开销。
  • readonly常量在第一次访问时初始化,性能上稍逊于const,但灵活性更高。
  • 在性能关键的代码中,应优先使用const常量。

示例

class Performance
{
    public const int Iterations = 1000;
    public readonly int Multiplier;

    public Performance(int multiplier)
    {
        Multiplier = multiplier;
    }

    public void Run()
    {
        for (int i = 0; i < Iterations; i++)
        {
            Console.WriteLine(i * Multiplier);
        }
    }
}

在这个示例中,Iterations作为编译时常量提供了最高的性能,而Multiplier作为运行时常量提供了更高的灵活性。

4. 不变性和线程安全

线程安全

  • const常量和readonly常量由于其不变性,本质上是线程安全的。在多线程环境中使用这些常量无需额外的同步措施。
  • 在编写多线程代码时,尽量使用不可变对象和常量来减少并发问题。

示例

class ThreadSafeConstants
{
    public const double Pi = 3.14159; // 线程安全
    public static readonly string ApplicationName = "MyApp"; // 线程安全
}

在这个示例中,PiApplicationName都是线程安全的常量,可以在多线程环境中安全使用。

5. 使用枚举定义常量

枚举

  • 枚举是一种特殊的常量集合,适用于定义一组相关的常量值。枚举提供了类型安全的常量定义方式,避免了魔法数的使用。
  • 枚举的每个成员都是一个常量,可以用来表示一组相关的命名常量。

示例

enum DaysOfWeek
{
    Sunday,
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday
}

class Program
{
    static void Main(string[] args)
    {
        DaysOfWeek today = DaysOfWeek.Wednesday;
        Console.WriteLine($"Today is: {today}");
    }
}

在这个示例中,我们使用枚举定义了一组表示星期几的常量,并使用它们来表示当前的星期。

练习

练习题1:使用constreadonly定义常量

问题
编写一个C#程序,定义一个使用const关键字的编译时常量和一个使用readonly关键字的运行时常量。初始化并输出这些常量的值。

答案

using System;

class Constants
{
    public const double Pi = 3.14159; // 编译时常量
    public readonly string Date;

    public Constants(string date)
    {
        Date = date; // 运行时常量
    }
}

class Program
{
    static void Main(string[] args)
    {
        Constants constants = new Constants(DateTime.Now.ToString("yyyy-MM-dd"));
        Console.WriteLine($"Pi: {Constants.Pi}");
        Console.WriteLine($"Date: {constants.Date}");
    }
}
练习题2:枚举的使用

问题
编写一个C#程序,使用枚举定义一组表示季节的常量。创建一个方法,根据传入的枚举值输出相应的季节名称。

答案

using System;

enum Seasons
{
    Spring,
    Summer,
    Autumn,
    Winter
}

class Program
{
    static void Main(string[] args)
    {
        PrintSeason(Seasons.Spring);
        PrintSeason(Seasons.Winter);
    }

    static void PrintSeason(Seasons season)
    {
        switch (season)
        {
            case Seasons.Spring:
                Console.WriteLine("Spring");
                break;
            case Seasons.Summer:
                Console.WriteLine("Summer");
                break;
            case Seasons.Autumn:
                Console.WriteLine("Autumn");
                break;
            case Seasons.Winter:
                Console.WriteLine("Winter");
                break;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值