Skip to content

C# - 变量

变量是内存中用于存储数据的命名位置。在 C# 中,每个变量都有一个特定类型,这决定了变量内存的大小和布局、可以存储的值范围以及可以对其应用的操作集。

在使用变量之前,您必须通过指定其类型和名称来声明它。您也可以在声明的同时初始化(赋值)它。

<type> <variableName> = <initialValue>;
// Declaring and initializing variables
string name = "Alice";
int score = 95;
bool isActive = true;
decimal price = 19.99m; // 'm' suffix for decimal literals

现代 C# 允许您使用 var 关键字声明变量,而无需显式声明其类型。编译器会根据右侧分配的值推断出类型。这可以使代码更简洁。

最佳实践:当类型从赋值的右侧显而易见时(例如,var user = new User();),使用 var。如果类型不明显或为了增强清晰度,请使用显式类型名称(例如,int totalCount = GetCount();)。

// Using 'var' for implicit typing
var customerName = "Bob"; // Compiler infers 'string'
var orderCount = 10; // Compiler infers 'int'
var product = new Product(); // Compiler infers 'Product' class

在 C# 中,类型根据其在内存中存储数据的方式进行分类:

值类型直接包含其数据。当一个值类型变量赋值给另一个变量时,其值会被复制。它们通常存储在栈(stack)上,这对于分配和清理来说速度很快。

  • 整型:int、long、byte、short
  • 浮点型:float、double、decimal
  • 其他类型:bool、char、structs、enums
int a = 10;
int b = a; // The value 10 is COPIED to b
b = 20; // Changing b does NOT affect a
Console.WriteLine($"a = {a}, b = {b}"); // Output: a = 10, b = 20

引用类型存储一个引用(或内存地址),指向堆(heap)中实际数据的位置。当一个引用类型变量赋值给另一个变量时,只复制引用,而不是对象本身。此时两个变量都指向同一个对象。

  • 内置类型:string、object
  • 用户定义类型:class、interface、delegate
  • 集合:arrays(例如 int[])、List<T>
int[] arrayA = { 1, 2, 3 };
int[] arrayB = arrayA; // The REFERENCE is copied. Both point to the same array.
arrayB[0] = 99; // Modifying the array through arrayB AFFECTS arrayA
Console.WriteLine($"arrayA[0] = {arrayA[0]}"); // Output: arrayA[0] = 99
  • const:值在编译时固定且不能更改。它是隐式静态的。用于真正的通用常量,如 Math.PI。
  • readonly:值可以在声明时或构造函数中赋值。对象创建后它变为不可变。用于在对象生命周期内不应更改的实例特定值。
public class Config
{
public const int MaxRetries = 3; // Compile-time constant
public readonly string ConnectionId; // Runtime constant
public Config(Guid id)
{
ConnectionId = $"conn_{id}"; // Can only be set here
}
}

现代 C# 强烈强调空安全(null safety),以防止臭名昭著的 NullReferenceException。您可以通过添加 ? 使值类型可空。对于引用类型,现代项目默认启用可空性检查,强制您处理潜在的 null 值。

#nullable enable // Enable nullable reference type checking
// Nullable value type
int? optionalValue = null;
if (optionalValue.HasValue)
{
Console.WriteLine($"Value is: {optionalValue.Value}");
}
// Nullable reference type
string? message = null; // The '?' indicates this string can be null
// Console.WriteLine(message.Length); // Compiler gives a warning here!
if (message != null)
{
Console.WriteLine(message.Length); // Safe to use within this block
}
  • 命名约定:局部变量使用 camelCase 命名(例如 int userAge;),公共属性和字段使用 PascalCase 命名(例如 public string UserName;)。
  • 描述性名称:选择能清晰描述变量用途的名称。customerAddress 比 adr 更好。
  • 最小化作用域:在变量所需最小的作用域内声明它们。这能提高可读性并减少错误。