일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- c#
- C언어 포인터
- docker
- git
- jupyter
- Algorithm
- c# 윈폼
- C++
- 깃
- 다트 언어
- jupyter lab
- 유니티
- C# delegate
- 플러터
- c# 추상 클래스
- gitlab
- 구조체
- github
- 포인터
- HTML
- Unity
- Flutter
- vim
- Python
- c# winform
- dart 언어
- c언어
- Data Structure
- 도커
- Houdini
- Today
- Total
nomad-programmer
[Programming/C#] ?? 연산자와 ??= 연산자 본문
??= 연산자는 C# 8.0 버전에서 추가된 아주 유용한 연산자 중 하나이다. ??= 연산자는 "null 병합 할당 연산자" 라고 부르며 ??= 연산자는 왼쪽 피연산자가 null로 평가되는 경우에만 오른쪽 피연산자의 값을 왼쪽 피연산제 대입한다. 왼쪽 피연산자가 null이 아닌것으로 평가되면 ??= 연산자는 오른쪽 피연산자를 평가하지 않는다.
?? 연산자는 "null 병합 연산자" 라고 부르며 null이 아닌 경우 왼쪽 피연산자의 값을 반환한다. 그렇지 않으면 오른쪽 피연산자를 평가하고 그 결과를 반환한다. ?? 연산자는 왼쪽 피연산자가 null 아닌 것으로 평가되면 ?? 연산자는 오픈쪽 피연산자를 평가하지 않는다.
if (variable is null)
{
variable = expression;
}
위의 코드는 다음과 같이 표현할 수 있다.
variable ??= expression;
다음의 코드는 ??= (null 병합 할당 연산자) 를 사용하지 않았을 때의 코드이다.
using System;
using System.Collections.Generic;
namespace test
{
class Program
{
static void Main(string[] args)
{
int? foo = null;
List<int> numbers = null;
if (numbers is null)
{
(numbers = new List<int>()).Add(5);
}
Console.WriteLine($"numbers: {string.Join(' ', numbers)}");
if(foo is null)
{
foo = 10;
numbers?.Add((int)foo);
}
else
{
numbers?.Add((int)foo);
}
Console.WriteLine($"numbers: {string.Join(' ', numbers)}");
Console.WriteLine($"foo: {foo}");
}
}
}
/* 결과
numbers: 5
numbers: 5 10
foo: 10
*/
다음의 코드는 ??= (null 병합 할당 연산자) 를 사용하였을 때의 코드다.
using System;
using System.Collections.Generic;
namespace test
{
class Program
{
static void Main(string[] args)
{
int? foo = null;
List<int> numbers = null;
// numbers가 null이라면 새로운 리스트를 생성후 numbers에 대입한다. 그 후 5를 넣는다.
(numbers ??= new List<int>()).Add(5);
Console.WriteLine($"numbers: {string.Join(' ', numbers)}");
// foo가 null이라면 foo 변수에다가 10을 대입하고 foo의 값을 numbers 리스트에 추가한다.
// 그렇지 않고 foo가 null이 아니라 값이 존재한다면 foo의 값을 numbers 리스트에 추가한다.
numbers?.Add(foo ??= 10);
Console.WriteLine($"numbers: {string.Join(' ', numbers)}");
Console.WriteLine($"foo: {foo}");
}
}
}
/* 결과
numbers: 5
numbers: 5 10
foo: 10
*/
null 병합 할당 연산자를 사용하니 코드가 상당히 깔끔해진것을 볼 수 있다. C# 8.0 버전부터 ?? 및 ??= 연산자의 왼쪽 피연산자 형식은 null을 허용하지 않는 값 형식일 수 없다.
??= 연산자의 왼쪽 피연산자는 변수, 속성 또는 인덱서 요소여야 한다.
결합 순서
a ?? b ?? c
d ??= e ??= f
위의 코드는 다음과 같은 결합 순서를 가진다.
a ?? (b ?? c)
d ??= (e ??= f)
?? 및 ??= 연산자의 유용한 사용 예
?? 및 ??= 연산자는 다음과 같은 상황에서 유용하게 사용할 수 있다.
1. null 병합 연산자 ?. 및 ?[] 가 있는 식에서 ?? 연산자를 사용하여 null 조건부 연산을 사용한 식의 결과가 null인 경우 평가하는 대체 식을 제공할 수 있다.
using System;
using System.Collections.Generic;
namespace test
{
class Program
{
public static double SumNumbers(List<double[]> setOfNumbers, int indexOfSetToSum)
{
// setOfNumbers가 null이 아니라면 indexOfSetToSum 숫자로 색인을 진행한다.
// 색인 결과가 null이 아닌 경우 Sum 메소드를 호출하여 List의 값을 모두 더한다.
// 그렇지않고 색인 결과가 null 이라면, NaN 을 반환한다.
return setOfNumbers?[indexOfSetToSum]?.Sum() ?? double.NaN;
}
static void Main(string[] args)
{
double sum = SumNumbers(null, 0);
Console.WriteLine($"sum: {sum}");
}
}
}
/* 결과
sum: NaN
*/
2. nullable 값 형식을 사용하고 기본값 유형의 값을 제공해야 할 때 ?? 연산자를 사용하여 nullable 값이 null 인 경우 제공할 값을 지정한다.
int? a = null;
int b = a ?? -1;
Console.WriteLine(b);
/* 결과
-1
*/
3. C# 7.0 부터 ?? 연산자의 오른쪽 피연산자로 throw 식을 사용하여 인수 확인 코드를 보다 간결하게 만들 수 있다.
public string Name
{
get => name;
set => name = value ?? throw new ArgumentNullException(nameof(value), "Name cannot be null");
}
'Programming > C#' 카테고리의 다른 글
[Programming/C#] 가비지 컬렉션 (Garbage Collection) (0) | 2020.10.04 |
---|---|
[Programming/C#] 프로토콜 설계와 네트워크 애플리케이션 프로그래밍 예제 (2) | 2020.10.04 |
[Programming/C#] TcpListener & TcpClient (5) | 2020.10.04 |
[Programming/C#] WinForm : 비동기 작업 (0) | 2020.10.03 |
[Programming/C#] WinForm : 시작과 종료 이벤트 (0) | 2020.10.03 |