C#中两个问号连在一起是什么意思

C#中两个问号连在一起是什么意思

技术背景

在C#编程中,有时会看到两个问号(??)连在一起的运算符,它在处理空值时非常有用。这是C#中的空合并运算符,在很多场景下能简化代码逻辑,提高代码的可读性和简洁性。

实现步骤

基本用法

空合并运算符(??)用于返回表达式链中的第一个非空值。其基本语法为:左操作数 ?? 右操作数。如果左操作数不为空,则返回左操作数;否则返回右操作数。

示例代码如下:

1
2
string formsAuth = null;
string FormsAuth = formsAuth ?? new string("FormsAuthenticationWrapper");

上述代码中,如果formsAuthnull,则FormsAuth将被赋值为new string("FormsAuthenticationWrapper");否则FormsAuth将被赋值为formsAuth

链式使用

空合并运算符可以链式使用,用于从多个可能为空的值中选择第一个非空值。

示例代码如下:

1
2
3
4
5
string Answer1 = null;
string Answer2 = null;
string Answer3 = "ValidAnswer";
string Answer4 = null;
string Answer = Answer1 ?? Answer2 ?? Answer3 ?? Answer4;

在这个例子中,Answer将被赋值为Answer3的值,因为它是第一个非空的变量。

与空条件运算符结合使用

空条件运算符(?.?[)通常与空合并运算符一起使用,用于在访问对象成员或索引之前检查对象是否为空。

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Customer
{
public Order Order { get; set; }
}

class Order
{
public int? Price { get; set; }
}

Customer customers = new Customer();
customers.Order = null;
int dollarAmount = customers?.Order?.Price ?? 0;

在这个例子中,如果customerscustomers.Ordercustomers.Order.Price 中的任何一个为nulldollarAmount 将被赋值为0;否则将被赋值为customers.Order.Price的值。

空合并赋值运算符

从C# 8.0开始,引入了空合并赋值运算符(??=),它可以进一步简化代码。

示例代码如下:

1
2
string myvariable = null;
myvariable ??= new string("MyValue");

上述代码等价于:

1
2
3
4
if (myvariable == null)
{
myvariable = new string("MyValue");
}

核心代码

基本用法示例

1
2
int? variable1 = null;
int variable2 = variable1 ?? 100;

链式使用示例

1
2
3
4
5
string str1 = null;
string str2 = null;
string str3 = "Hello";
string str4 = null;
string final = str1 ?? str2 ?? str3 ?? str4;

与空条件运算符结合使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
class Person
{
public Address Address { get; set; }
}

class Address
{
public string City { get; set; }
}

Person person = new Person();
person.Address = null;
string city = person?.Address?.City ?? "Unknown";

空合并赋值运算符示例

1
2
string message = null;
message ??= "Default Message";

最佳实践

  • 避免重复创建对象:在使用空合并运算符时,要注意避免不必要的对象创建。例如:
1
2
3
4
5
private FormsAuthenticationWrapper _formsAuthWrapper;
public FormsAuthenticationWrapper FormsAuthWrapper
{
get { return _formsAuthWrapper = _formsAuthWrapper ?? new FormsAuthenticationWrapper(); }
}

这样可以确保只有在_formsAuthWrappernull时才创建新对象。

  • 提高代码可读性:合理使用空合并运算符和空合并赋值运算符可以使代码更加简洁和易读。例如,使用myVariable ??= defaultValue;代替传统的if语句。

常见问题

不能用于非可空类型

空合并运算符只能用于可空类型。如果尝试在非可空类型上使用,会导致编译错误。例如:

1
2
3
int a = 1;
// 下面的代码会编译错误
// a = a ?? 2;

运算符优先级问题

在复杂的表达式中,要注意空合并运算符的优先级。必要时可以使用括号来明确运算顺序。例如:

1
2
int? x = null;
int result = (x ?? 5) * 2;

这样可以确保先处理空合并运算,再进行乘法运算。


C#中两个问号连在一起是什么意思
https://119291.xyz/posts/what-do-two-question-marks-together-mean-in-csharp/
作者
ww
发布于
2025年5月23日
许可协议