导读:本期聚焦于小伙伴创作的《C#中有最终变量吗?如何实现类似最终变量的不可变效果》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C#中有最终变量吗?如何实现类似最终变量的不可变效果》有用,将其分享出去将是对创作者最好的鼓励。

在Java中,final关键字可以修饰变量使其变为最终变量,赋值后无法再修改。C#并没有直接对应final变量的语法,但提供了多种机制来实现类似的不可变效果,开发者可以根据变量的作用域、赋值时机等需求选择合适的方案。

C#实现不可变变量的常用方案

1. 使用const关键字

const关键字用于定义编译时常量,一旦定义就完全不可修改,且必须在声明时直接赋值,值必须是编译期可确定的常量表达式。

适用场景:定义全局固定不变的值,比如数学常量、固定配置项等。

// 定义const常量,声明时必须赋值
public const double Pi = 3.1415926;
public const string AppName = "MyApplication";

class Program
{
    static void Main()
    {
        // 尝试修改const变量会直接编译报错
        // Pi = 3.14; 这行代码无法通过编译
        Console.WriteLine($"圆周率:{Pi}");
        Console.WriteLine($"应用名称:{AppName}");
    }
}

2. 使用readonly关键字

readonly关键字用于定义运行时常量,只能在声明时或者所属类的构造函数中赋值,一旦赋值后就无法再修改,比const更灵活,支持运行时确定值。

适用场景:实例级别的不可变字段,或者需要在运行时根据参数确定值的不可变变量。

public class User
{
    // readonly字段,声明时赋值
    public readonly string Id;
    // readonly字段,构造函数中赋值
    public readonly string Name;

    public User(string id, string name)
    {
        Id = id;
        Name = name;
        // 构造函数外无法再修改readonly字段
    }

    public void UpdateName()
    {
        // 这里尝试修改会编译报错
        // Name = "NewName";
    }
}

class Program
{
    static void Main()
    {
        User user = new User("1001", "张三");
        Console.WriteLine($"用户ID:{user.Id},用户名:{user.Name}");
    }
}

3. 使用不可变类型

如果需要整个对象的所有属性都不可修改,可以定义不可变类型,比如使用record类型(C# 9.0及以上支持),或者手动定义只有get访问器的属性。

// 使用record定义不可变类型,属性默认是init访问器,只能在初始化时赋值
public record Point(int X, int Y);

// 手动定义不可变类
public class ImmutableConfig
{
    public string ServerUrl { get; }
    public int Port { get; }

    public ImmutableConfig(string serverUrl, int port)
    {
        ServerUrl = serverUrl;
        Port = port;
    }
}

class Program
{
    static void Main()
    {
        Point p = new Point(10, 20);
        // 尝试修改属性会编译报错
        // p.X = 30;

        ImmutableConfig config = new ImmutableConfig("http://ipipp.com", 8080);
        // config.Port = 9090; 这行会编译报错
        Console.WriteLine($"服务地址:{config.ServerUrl},端口:{config.Port}");
    }
}

4. 局部不可变变量

在方法内部,如果需要定义不可修改的局部变量,可以使用var配合初始化,或者使用let?不对,C#中没有let,实际上局部变量如果不希望被修改,只需要遵循编码规范不重新赋值即可,也可以使用readonly修饰局部变量?不对,C#中readonly不能修饰局部变量,正确的方式是使用in参数或者编码约束,另外C# 7.0及以上支持ref readonly局部变量,不过更常用的还是通过编码规范保证局部变量不被修改,或者使用不可变集合。

如果是需要不可变的局部集合,可以使用System.Collections.Immutable命名空间下的不可变集合类型。

using System.Collections.Immutable;

class Program
{
    static void Main()
    {
        // 创建不可变数组
        ImmutableArray<int> numbers = ImmutableArray.Create(1, 2, 3, 4);
        // 尝试修改会报错,不可变集合的方法会返回新的集合而不是修改原集合
        // numbers[0] = 10; 编译报错
        ImmutableArray<int> newNumbers = numbers.Add(5);
        Console.WriteLine($"原集合长度:{numbers.Length},新集合长度:{newNumbers.Length}");
    }
}

不同方案的区别对比

方案赋值时机作用范围适用场景
const声明时全局/类级别编译期确定的固定常量
readonly声明时或构造函数类/实例字段运行时确定的实例不可变字段
不可变类型初始化时对象级别整个对象属性不可修改
不可变集合创建时集合级别集合元素不可修改

注意事项

  • const变量是隐式静态的,不需要也不能加static修饰符,访问时直接通过类名访问。
  • readonly字段如果是静态的,需要加static修饰符,且只能在静态构造函数中赋值。
  • 不可变类型只是属性不能修改,如果属性是引用类型,引用类型内部的属性还是可以修改的,需要实现深不可变才能保证完全不可变。
总结:C#虽然没有名为最终变量的语法,但通过const、readonly、不可变类型、不可变集合等方案,完全可以覆盖Java最终变量的所有使用场景,开发者可以根据实际需求选择最合适的实现方式。

C#final_variablereadonlyconstimmutable修改时间:2026-06-11 13:36:40

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。