Section 8.3: NullReferenceException 방지하기

var person = new Person { Address = null; }; var city = person.Address.City; // NullReferenceException 을 throw 할 것이다 var nullableCity = person.Address?.City; // null 값을 반환한다

이러한 효과는 함께 연결하여 (chained together) 사용될 수 있다:

var person = new Person { Address = new Address { State = new State { Country = null } } }; // 아래 코드는 각 변수들의 값 상태에 따라 countryName 에 null 값이 저장되는 한이 있더라도 // 최소한 NullReferenceException 이 throw 되지는 않도록 해줄 것이다 var countryName = person?.Address?.State?.Country?.Name;
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

Section 8.2: Null 조건부 인덱스 (index)

?. 연산자와 유사하게, null 조건부 인덱스 연산자는 null 일 가능성이 있는 collection 에 대해 인덱스에 해당하는 요소를 찾기 전에 null 체크를 먼저 수행한다.

string item = collection?[index];

이는 아래의 코드에 해당하는 syntactic sugar 로 볼 수 있다.

string item = null; if(collection != null) { item = collection[index]; }
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

Section 8.1: Null 조건부 연산자

?. 연산자는 귀찮은 null check 들을 생략할 수 있도록 도와주는 일종의 syntactic sugar 이다. 이는 "safe navigation 연산자" 라는 또다른 표현으로 알려져 있기도 하다.

예제를 위한 다음 클래스 선언을 살펴본다:

public class Person { public int Age { get; set; } public string Name { get; set; } public Person Spouse { get; set; } }

만약 어떤 객체가 잠재적으로 null 일수 있는 경우 (예를 들어 특정 함수가 reference 타입을 반환한다거나), 발생할지 모르는 NullReferenceException 을 방지하기 위하여, 해당 객체에 대해 우선적으로 null 체크를 수행하여야 한다. null 조건부 연산자가 없는 상황을 가정해 보면, 아래와 같은 코드를 작성해야 할 것이다:

Person person = GetPerson(); int? age = null; if (person != null) age = person.Age;

같은 null 체크를 null 조건부 연산자를 이용하여 구현하면 다음과 같다:

Person person = GetPerson(); var age = person?.Age; // 'age' 는 'person' 이 null 이 아니라 할지라도 'int?' 타입을 가지게 된다

연산자 연결 (chaining) 하기

null 조건부 연산자는 객체의 멤버 및 멤버 객체의 멤버 (sub-member) 에 대해 결합하여 사용할 수 있다.

// `person` 혹은 `person.Spouse` 중 하나만 null 이어도 null 이 될 것이다 int? spouseAge = person?.Spouse?.Age;

null 병합 (coalescing) 연산자와 결합하여 사용하기

null 조건부 연산자는 기본값을 제공하기 위하여 null 병합 연산자와 결합하여 사용될 수 있다:

// spouseDisplayName 은 person, Spouse, 혹은 Name 중 하나라도 null 인 경우 "N/A" 값을 갖게 될 것이다 var spouseDisplayName = person?.Spouse?.Name ?? "N/A";
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

Section 7.5: Null 병합 연산자를 이용한 property 초기화 지연 (lazy initialization)

private List < FooBar > _fooBars; public List < FooBar > FooBars { get { return _fooBars ?? (_fooBars = new List < FooBar > ()); } }

.FooBars property 가 최초로 액세스되는 시점에는 _fooBars 변수가 null 인 상태일 것이므로, 할당 구문이 곧바로 실행될 것이며 액세스의 최종 결과는 해당 할당 구문의 결과값으로 평가 (evaluate) 될 것이다.

Thread safety

위 예제에서 소개된 지연된 (lazy) property 는 thread safe 한 방법으로 구현되어 있지 않다. thread safe 한 구현을 위해서는, .NET Framework 의 일부분으로 포함되어 있는 Lazy<T> 클래스를 이용하도록 한다.

표현식 본문을 이용한 C# 6 의 Syntactic Sugar

C# 6 이후부터는, 위 문법이 property 에 대한 표현식 본문 (expression body) 을 사용하여 보다 단순화될 수 있다:

private List<FooBar> _fooBars; public List<FooBar> FooBars => _fooBars ?? ( _fooBars = new List<FooBar>() );

최초 할당 이후의 property 에 대한 액세스는 _fooBars 변수에 저장된 값을 사용하게 될 것이다.

MVVM 패턴에서의 사용 예제

이러한 방법은 MVVM 패턴에서 command 를 구현할 때 주로 사용될 것이다. 각 command 들을 view model 생성시에 즉시 (eagerly) 초기화하는 대신, command 들은 다음과 같이 위에서 소개된 패턴을 이용하여 지연되어 (lazily) 초기화 될 것이다:

private ICommand _actionCommand = null; public ICommand ActionCommand => _actionCommand ?? ( _actionCommand = new DelegateCommand( DoAction ) );
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

Section 7.4: 기존 객체를 사용하거나 없는 경우 새로 생성하기

Null 병합 연산자를 사용함에 있어서 도움이 되는 흔한 사용 시나리오는 바로 collection 에서 객체를 검색한 후, 조건에 맞는 객체가 있으면 검색된 객체를 사용하고 없으면 새로운 객체를 생성하는 것이다.

IEnumerable<MyClass> myList = GetMyList(); var item = myList.SingleOrDefault(x => x.Id == 2) ?? new MyClass { Id = 2 };
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

Section 7.3: Null 병합 연산자를 메소드 호출 결과에 사용하기

Null 병합 연산자를 사용하면 null 값을 반환할수도 있는 메소드 호출 시, null 값이 반환된 경우 미리 정의된 기본 값을 대신해 사용하는 작업을 손쉽게 구현할 수 있다.

Null 병합 연산자 미사용 시:

string name = GetName(); if (name == null) name = "Unknown!";

Null 병합 연산자 사용 시:

string name = GetName() ?? "Unknown!";
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

Section 7.2: Null fall-through 와 chaining

Null 병합 (coalescing) 연산자 사용 시 좌측 피연산자는 nullable 타입이어야 하며, 우측 피연산자는 nullable 일 수도, 아닐 수도 있다. 최종 결과값의 타입은 자동으로 적절하게 결정될 것이다.

우측 피 연산자가 Non-nullable 인 경우

int? a = null; int b = 3; var output = a ?? b; var type = output.GetType(); Console.WriteLine($"Output Type :{type}"); Console.WriteLine($"Output value :{output}");

출력 결과:

Type :System.Int32 value :3

Demo 확인하기

우측 피 연산자가 Nullable 인 경우

int? a = null; int? b = null; var output = a ?? b;

결과값의 타입은 int? 가 될 것이며 그 값은 b, 혹은 null 이 될 것이다.

다중 병합 (Multiple Coalescing)

병합 (Coalescing) 연산은 연결되어 사용될 수 있다:

int? a = null; int? b = null; int c = 3; var output = a ?? b ?? c; var type = output.GetType(); Console.WriteLine($"Type :{type}"); Console.WriteLine($"value :{output}");

출력 결과:

Type :System.Int32 value :3

Demo 확인하기

Null 조건부 Chaining

Null 병합 (coalescing) 연산자는 null 조건부 연산자와 연계하여 객체의 property 에 대한 보다 안전한 접근을 제공할 수 있다.

object o = null; var output = o?.ToString() ?? "Default Value";

출력 결과:

Type :System.String value :Default Value

Demo 확인하기

본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

Section 7.1: Null 병합 (coalescing) 연산자의 기본 사용법

파라미터 설명
possibleNullObject null 인지 검사를 수행할 값. 만약 null 이 아니면, 이 값이 반환될 것이다. 이 값은 반드시 nullable 타입이어야 한다.
defaultValue possibleNullObjectnull 인 경우에 반환할 값. possibleNullObject 와 동일한 타입이어야 한다

null 병합 (coalescing) 연산자 (??) 를 사용하면 nullable 타입에 대해서 좌측 피연산자가 null 인 경우에 대한 기본값을 지정할 수 있다.

string testString = null; Console.WriteLine("The specified string is - " + (testString ?? "not provided"));

.NET Fiddle 에서의 Live Demo 보기

위 예제는 논리상 아래의 예제와 동등한 효과를 갖는다:

string testString = null; if (testString == null) { Console.WriteLine("The specified string is - not provided"); } else { Console.WriteLine("The specified string is - " + testString); }

혹은 삼항 연산자 (?:) 를 사용할 수도 있다:

string testString = null; Console.WriteLine("The specified string is - " + (testString == null ? "not provided" : testString));
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

+ Recent posts