C# 类型后的问号?

本文详细介绍了C#中的单问号和双问号运算符的应用场景及用法。单问号用于给变量设定初始值为null而非0,而双问号则用于条件赋值:当左侧表达式为null时才执行右侧的赋值操作。

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

单问号---用于给变量设初值的时候,给变量(int类型)赋值为null ,而不是0!
双问号---用于判断并赋值,先判断当前变量是否为null,如果是就可以赋一个新值,否则跳过!

 

public int ? para;

// public int para;如果不注释掉此行,而把上一行注释掉的话,下面会报错!

public int par() { return this .para ?? 0 ; }

<think>我们正在讨论的是C#中的两个运算符:`?.`(空条件运算符)和`??`(空合并运算符)。在语句`selectedNode.Parent?.Nodes ?? uiTreeView.Nodes`中,它们分别用于简化空值检查和提供默认值。 ### 1. 空条件运算符 `?.`(也称为Elvis运算符) - **作用**:用于在访问成员之前检查对象是否为null。如果对象为null,则整个表达式返回null,而不会引发`NullReferenceException`。 - **语法**:`object?.Member` - **示例**: ```csharp // 传统写法 string name = null; if (person != null) { name = person.Name; } // 使用空条件运算符 string name = person?.Name; // 如果person为null,则name为null ``` 在`selectedNode.Parent?.Nodes`中: - 如果`selectedNode.Parent`不为null,则返回`Parent.Nodes`(即父节点的子节点集合)。 - 如果`selectedNode.Parent`为null,则整个表达式返回null。 ### 2. 空合并运算符 `??` - **作用**:用于为可空类型或引用类型提供默认值。如果左侧操作数为null,则返回右侧操作数;否则返回左侧操作数。 - **语法**:`leftOperand ?? rightOperand` - **示例**: ```csharp string name = null; string displayName = name ?? "Unknown"; // displayName为"Unknown" ``` 在`selectedNode.Parent?.Nodes ?? uiTreeView.Nodes`中: - 如果`selectedNode.Parent?.Nodes`不为null,则使用该值。 - 如果为null(即`selectedNode.Parent`为null),则使用`uiTreeView.Nodes`(即TreeView的根节点集合)。 ### 3. 整个表达式的含义 该表达式用于获取当前选中节点的兄弟节点集合(同一层级): - 如果节点有父节点(`Parent`不为null),则兄弟节点集合为`Parent.Nodes`。 - 如果节点是根节点(`Parent`为null),则兄弟节点集合为TreeView的根节点集合(`uiTreeView.Nodes`)。 ### 4. 与传统写法的对比 传统写法: ```csharp TreeNodeCollection siblingNodes; if (selectedNode.Parent != null) { siblingNodes = selectedNode.Parent.Nodes; } else { siblingNodes = uiTreeView.Nodes; } ``` 使用运算符后的简化写法: ```csharp TreeNodeCollection siblingNodes = selectedNode.Parent?.Nodes ?? uiTreeView.Nodes; ``` ### 5. 注意事项 - `?.`运算符可以链式使用:`obj?.Property?.SubProperty`。 - `??`运算符的右侧操作数可以是任何与左侧类型兼容的表达式,包括方法调用。 - 两者结合使用可以极大简化空值处理代码。 ### 6. 相关扩展:空合并赋值运算符 `??=`(C# 8.0+) - **作用**:仅在左侧操作数为null时,将右侧操作数的值赋给左侧操作数。 - **示例**: ```csharp List<int> numbers = null; numbers ??= new List<int>(); // 如果numbers为null,则初始化 ``` ### 总结 在TreeView节点处理中,使用`?.`和`??`运算符能够: 1. 安全地访问可能为null的对象成员[^1] 2. 简洁地提供默认值 3. 避免冗长的空值检查代码 这种写法在需要处理树形结构节点层级时非常实用,尤其适用于TreeView、XML文档等场景。 --- ### 相关问题 1. C# 中还有哪些简化空值处理的语法特性? 2. 如何避免在多层嵌套对象中出现的`NullReferenceException`? 3. C# 8.0 的可空引用类型Nullable Reference Types)如何与这些运算符配合使用? 4. 在异步编程中如何安全地处理可能为null的对象? 5. 如何自定义一个类以支持空条件运算符? [^1]: TreeView 控件的节点操作和空值处理</think>### C# 中 `?.` 和 `??` 运算符详解 在语句 `selectedNode.Parent?.Nodes ?? uiTreeView.Nodes` 中,`?.` 和 `??` 是两个不同的空值处理运算符,它们共同作用使代码更简洁安全: #### 1. 空条件运算符 `?.`(Null-conditional operator) - **含义**:安全访问可能为 null 的对象的成员 - **作用**:当左侧对象为 null 时,整个表达式返回 null,避免 `NullReferenceException` - **示例**: ```csharp // 传统写法(需显式空值检查) TreeNodeCollection nodes = null; if (selectedNode.Parent != null) { nodes = selectedNode.Parent.Nodes; } // 使用 ?. 运算符(等效但更简洁) var nodes = selectedNode.Parent?.Nodes; ``` 在 `selectedNode.Parent?.Nodes` 中: - 若 `selectedNode.Parent` 不为 null → 返回 `Parent.Nodes` - 若 `selectedNode.Parent` 为 null → 返回 `null` #### 2. 空合并运算符 `??`(Null-coalescing operator) - **含义**:为 null 值提供回退方案 - **作用**:当左侧表达式为 null 时,返回右侧表达式的值 - **示例**: ```csharp // 传统写法 TreeNodeCollection finalNodes = nodes != null ? nodes : uiTreeView.Nodes; // 使用 ?? 运算符 var finalNodes = nodes ?? uiTreeView.Nodes; ``` #### 3. 组合使用 `?.` 和 `??` 在完整语句 `selectedNode.Parent?.Nodes ?? uiTreeView.Nodes` 中: 1. 首先执行 `?.`:尝试获取父节点的子节点集合 2. 若结果为 null(无父节点),则执行 `??`:返回 TreeView 的根节点集合 3. 最终结果: - 有父节点 → 返回父节点的子节点集合 - 无父节点(根节点)→ 返回 TreeView 的根节点集合 #### 4. 与传统写法的对比 ```csharp // 传统写法(多层嵌套空值检查) TreeNodeCollection siblingNodes; if (selectedNode.Parent != null) { siblingNodes = selectedNode.Parent.Nodes; } else { siblingNodes = uiTreeView.Nodes; } // 现代写法(单行表达式) var siblingNodes = selectedNode.Parent?.Nodes ?? uiTreeView.Nodes; ``` #### 5. 实际应用场景 在 TreeView 节点处理中,这种写法特别适用于: ```csharp // 获取当前节点的同级节点(兄弟节点) TreeNodeCollection siblings = selectedNode.Parent?.Nodes ?? treeView.Nodes; // 判断节点位置 bool isFirst = siblings.IndexOf(selectedNode) == 0; bool isLast = siblings.IndexOf(selectedNode) == siblings.Count - 1; ``` #### 注意事项 1. `?.` 可链式使用:`obj?.Property?.SubProperty?.Method()` 2. `??` 右侧可以是:默认值、新对象、方法调用等 3. C# 8.0+ 支持空合并赋值 `??=`: `nodes ??= new TreeNodeCollection();` > 这些运算符大幅简化了空值处理逻辑,使代码更健壮且易读[^1][^3]。 --- ### 相关问题 1. C# 中如何安全调用可能为 null 对象的方法? 2. `??` 运算符与三元运算符 `?:` 有何区别? 3. C# 8.0 的可空引用类型如何与这些运算符配合使用? 4. 在异步编程中如何处理潜在的空引用问题? 5. 如何自定义一个类以支持空条件运算符?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值