C# 中鲜为人知的强大运算符
C# 还提供了一些"冷门"但功能强大的运算符,这些运算符在特定场景下能极大简化代码并提高效率。
1. 空合并赋值运算符 ??=
// 传统写法
if (variable == null)
{variable = defaultValue;
}// 使用 ??=
variable ??= defaultValue;
功能:
当变量为 null
时,将右侧的值赋给它
实际应用:
// 延迟初始化
private List<Item> _items;
public List<Item> Items => _items ??= new List<Item>();// 配置默认值
void LoadSettings()
{_qualityLevel ??= QualityLevel.High;_resolution ??= new Resolution(1920, 1080);
}
2. 空条件运算符 ?.
和 ?[]
// 安全访问成员
string name = user?.Profile?.Name;// 安全访问索引器
int? firstScore = scores?[0];// 安全调用方法
user?.Validate();
功能:
在访问成员、调用方法或访问索引器时,如果对象为 null
,则返回 null
而不是抛出异常
实际应用:
// Unity 中安全访问组件
Rigidbody rb = go?.GetComponent<Rigidbody>();// 安全访问字典值
var config = settings?.GetSection("Graphics")?["Resolution"];
3. 范围运算符 ..
int[] numbers = { 0, 1, 2, 3, 4, 5 };
var slice = numbers[1..4]; // [1, 2, 3]
var allButFirst = numbers[1..]; // [1, 2, 3, 4, 5]
var lastThree = numbers[^3..]; // [3, 4, 5]
功能:
创建数组或集合的切片视图
实际应用:
// 处理部分数据
ProcessFrames(videoFrames[10..20]);// 获取子字符串
string domain = email[(email.IndexOf('@') + 1)..];
4. 索引运算符 ^
int[] numbers = { 0, 1, 2, 3, 4, 5 };
int last = numbers; // 5
int secondLast = numbers; // 4
功能:
从集合末尾开始索引
实际应用:
// 获取路径最后部分
string fileName = path.Split('/');// 检查最后几个元素
if (samples[^3..].All(s => s > threshold))
{// 最后三个样本都超过阈值
}
5. 模式匹配中的 is
和 switch
表达式
// is 模式匹配
if (obj is string { Length: > 5 } s)
{Console.WriteLine($"长字符串: {s}");
}// switch 表达式
var message = input switch
{int i when i > 0 => "正数",int i when i < 0 => "负数",int => "零",_ => "非数字"
};
功能:
强大的类型检查和值提取
实际应用:
// Unity 组件处理
void ProcessComponent(Component comp)
{switch (comp){case Rigidbody rb:rb.velocity = Vector3.zero;break;case Renderer rend when rend.material != null:rend.material.color = Color.red;break;case null:Debug.LogWarning("组件丢失");break;}
}
6. 弃元运算符 _
// 忽略不需要的输出参数
_ = int.TryParse("123", out _);// 忽略不需要的返回值
_ = Task.Run(() => BackgroundProcess());// 模式匹配中忽略部分值
if (point is (0, _))
{// X坐标为0的所有点
}
功能:
明确表示忽略某个值
实际应用:
// Unity 事件处理
button.onClick.AddListener(_ =>
{// 不需要事件参数PlaySound();
});// 解构忽略部分值
var (x, _, z) = GetPosition();
7. 命名参数和可选参数
void ConfigureServer(string host, int port = 8080, bool ssl = false)
{// ...
}// 调用时
ConfigureServer("example.com", ssl: true);
功能:
提高代码可读性并简化重载
实际应用:
// Unity 实例化对象
Instantiate(prefab, position: spawnPoint.position,rotation: Quaternion.identity,parent: transform
);// 创建颜色
var color = new Color(r: 0.5f, g: 0.7f, b: 1f);
8. 插值字符串 $
string name = "Alice";
int age = 30;
string message = $"{name} is {age} years old";
功能:
更简洁的字符串格式化
高级用法:
// 格式控制
$"Price: {price:C2}" // 货币格式// 表达式计算
$"Area: {width * height}"// 对齐
$"{"Name",-10} {"Age",5}"
9. 联合 switch
表达式
var result = operation switch
{"add" => a + b,"sub" => a - b,"mul" => a * b,"div" when b != 0 => a / b,_ => throw new InvalidOperationException()
};
功能:
更简洁的模式匹配语法
实际应用:
// Unity 状态处理
currentState = input switch
{InputType.Jump when isGrounded => PlayerState.Jumping,InputType.Attack => PlayerState.Attacking,InputType.Dash when canDash => PlayerState.Dashing,_ => currentState
};
10. 委托合并运算符 +
和 -
event Action OnEvent;void Subscribe()
{OnEvent += Handler1;OnEvent += Handler2;
}void Unsubscribe()
{OnEvent -= Handler1;
}
功能:
管理事件订阅
实际应用:
// Unity 事件管理
button.onClick.AddListener(OnClick);
// ...
button.onClick.RemoveListener(OnClick);// 多播委托
Action multiAction = MethodA;
multiAction += MethodB;
multiAction(); // 调用 MethodA 和 MethodB
实用技巧:组合使用运算符
// 安全访问并设置默认值
string username = user?.Profile?.Name ?? "Guest";// 安全访问数组元素
int? score = scores?[index] ?? 0;// 模式匹配与空检查
if (obj is Player { Health: > 0 } player)
{player.Respawn();
}
这些运算符虽然相对"冷门",但在实际开发中能极大提升代码的简洁性。