C# 变量声明与作用域

变量是程序里"装数据的盒子"。C# 是一门静态强类型语言,每个变量都有明确的类型,编译器在编译期检查类型匹配——类型不对直接报错。这一篇我们搞懂 C# 变量的几种声明方式、常量、作用域规则。

一、三种声明方式

C# 里声明变量主要有三种写法,日常开发中最常用的是 var(配合强类型推断)。先看一个综合示例:

// 1. 显式声明:类型 + 变量名 + 可选初值
int age = 25;
double price = 9.99;
string name = "小明";
bool isStudent = true;

// 2. var:让编译器推断类型(局部变量常用)
var city = "北京";       // string
var count = 100;         // int
var nums = new int[] {1, 2, 3};   // int[]

// 3. 先声明后赋值(不推荐,容易忘初始化)
int score;
score = 88;

几个要点:

var 的好处是简洁——尤其是类型名很长时(如 Dictionary<string, List<int>>)。但要注意:var 只能用于局部变量,不能用于字段、参数、返回值;必须有初值供编译器推断。

二、命名规范

C# 变量命名遵循camelCase(小驼峰),首字母小写:

命名要"见名知意",userAgea 好,activeUserCountcount 好。这是写可维护代码的基础。

三、常量:const 与 readonly

"常量"是不能修改的值。C# 有两个相关关键字,容易混淆:

// const:编译时常量,必须初始化,之后不能改
const double Pi = 3.14159;
const int MaxRetry = 3;
const string AppName = "MyApp";

// ❌ 错误:const 不能改
// Pi = 3.14;

// readonly:运行时常量(只能在声明时或构造函数里赋值)
public class Configuration
{
    public readonly DateTime CreatedAt;
    public Configuration()
    {
        CreatedAt = DateTime.Now;   // 运行时才知道的值
    }
}

区别如下:

简单记:能用 const 就用 const(编译器优化更好);如果值需要运行时确定(如 DateTime.Now)或要每个实例不同,就用 readonly。

四、默认值

C# 保证所有变量都有确定的初始值。字段(类成员)即使你不显式赋值,也会被自动初始化为默认值;但局部变量必须先赋值再读,否则编译报错。默认值规则:

可以用 default 关键字显式获取:

using System;

// default 关键字获取类型的默认值
int a = default;          // 0
bool b = default;         // false
string c = default;       // null
DateTime d = default;     // 0001-01-01 00:00:00

// 显式写法:default(T)
int e = default(int);     // 0

五、变量的作用域

作用域指变量"在哪些代码范围里能被访问"。C# 的作用域分三层:

using System;

public class Demo
{
    private int instanceField = 10;       // 字段(类作用域)

    public void Method()
    {
        int local = 20;                  // 局部变量(方法作用域)
        if (true)
        {
            int block = 30;              // 块作用域
            Console.WriteLine(block);    // 30
        }
        // ❌ 错误:block 在这里不可见
        // Console.WriteLine(block);
    }
}

规则:内层可以访问外层,外层不能访问内层;如果内外层同名,内层遮蔽外层(C# 会发出警告,建议改名避免)。

六、类型推断 vs 动态类型

var编译期推断,编译完类型就固定了,不是动态类型。如果你想要运行时改变类型,可以用 dynamic(C# 4+),但不推荐——会绕过编译期检查,容易运行时崩溃:

// var:编译期确定类型
var x = 10;
// x = "hello";   // ❌ 编译报错,x 是 int

// dynamic:运行时确定类型(慎用)
dynamic y = 10;
y = "hello";      // ✅ 编译通过,但 y = "a" + 1 这种隐藏 bug 难发现

// object:类似 dynamic 但要装箱,访问成员需类型转换
object z = 10;
int n = (int)z;   // 显式转换

实际开发 99% 用 vardynamic 主要在调用 Python、COM、JSON 解析等场景用,日常慎用。

七、字符串插值

这是初学者最先接触到的"小而美"特性——字符串前加 $,用花括号嵌入变量:

string name = "小明";
int age = 20;

// 字符串插值(C# 6+ 推荐)
string s1 = $"我叫{name},今年{age}岁。";
// 我叫小明,今年20岁。

// 传统拼接(可读性差)
string s2 = "我叫" + name + ",今年" + age + "岁。";

// string.Format(老写法)
string s3 = string.Format("我叫{0},今年{1}岁。", name, age);

// 还能在花括号里写表达式
string s4 = $"明年我{age + 1}岁";

字符串插值是 C# 写法的现代首选,可读性碾压拼接和 Format。

小结

记住这几条就够用了:局部变量优先用 var,字段写显式类型;常量用 const(编译时)或 readonly(运行时);变量必须先赋值再用;作用域跟着花括号走。下一篇我们看 C# 的数据类型系统——这是强类型语言的核心。

← 上一篇 C# 基础语法

下一篇 C# 数据类型

✈️💬