NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 학습
  • 매뉴얼

    학습


    C# 26. C#의 nullable type과 null coalescing(??) 연산자.

    페이지 정보

    본문

    안녕하세요. 소심비형입니다. 오늘은 null에 관련된 내용을 알아보겠습니다. 우선, 타이틀에 있는 nullable과 null coalescing(??: 널 병합 연산자)에 대해 알아보기 전에 null에 대해 이해하고 있어야 합니다. 지금까지 홈페이지의 C# 관련 예제를 만들면서 코드 사이사이에 null을 사용해 왔는데요. 자세하게 언급하지는 않았죠? 그래도 어느정도 깊이 있게 관련 내용들을 모아서 정리하려고 그랬습니다-_-;

    LEJ7xd0.gif

     

     

    null이란?

    null은 "값이 없다"는 뜻입니다. 그렇다고해서 Empty("") 또는 Zero(0)와 같은 의미를 가지는 것은 아닙니다. 실세계에서는 비슷해 보일지도 모르겠지만, 컴퓨터의 세계에서는 전혀 다른 의미로 사용되기 때문입니다. 우선 컴퓨터는 메모리 공간에 데이터를 저장하고 이 데이터를 가져와서 연산이나 어떤 처리를 하게 됩니다. 이 때 내가 어떤 메모리 공간에서 데이터를 가져올지 또는 데이터를 기록할지 알아야 하고, 이 역할을 C에서는 포인터 변수가 담당하고 있습니다. Empty나 Zero의 경우에는 메모리의 어떤 주소에 빈값 또는 0이라는 값이 기록되어 있는 상태죠. null은 메모리 주소가 아직 할당되지 않은 상태를 나타냅니다.

     

    메모리 주소가 없기 때문에 어떤 연산도 처리할 수 없게 되겠죠? 하지만, 이게 또 항상 그런것은 아닙니다. null도 자료형이기 때문에 어느정도 제약이 있기는 하지만 연산도 되고, 비교도 됩니다. 좀 예외적인 내용이기는 하지만, C와 Java의 경우에는 비교 연산자가 2개 존재합니다. 일반적으로 "=="를 사용하고 있지만, "==="를 사용하기도 합니다. 이는 약간의 차이가 존재하는데  비교와 값 + 형식비교입니다. 이런 이유는 많은 시스템들이 null과 0을 구분하지 못하기 때문입니다. 물론, C#도 값 + 형식비교가 가능합니다.

    n7msN47.gif

     

     

    수많은 시스템에서 null로 인해 치뤄야 하는 비용은 엄청납니다. null에 대한 충분한 이해 없이 시스템 또는 클래스를 설계했다면, 나중에 상당히 큰 수정이 가해질수도 있습니다. 특히나 데이타베이스에서 사용하는 null과 호환이 되지 않는다면 말이죠. 하지만, C#은 이 부분에 대해서도 신경써줬습니다. 쉽게 처리가 가능하도록 말이죠. 그렇다하더라도 사이즈가 커지고 복잡도가 높은 시스템이라면 일일이 대응하는 것은 사실상 불가능에 가깝습니다. 그래서, 예외 또는 바이패스(bypass)할 수 있는 코드를 심게되는데 이런것들이 많아질수록 스파게티 소스가 될 확률이 높습니다. 정상적인 상황이라면 당연히 리팩토링을 해야 합니다.

    gKc8H7I.png

     

     

    C#은 null에 대해 보다 쉽게 처리할 수 있도록 많은 기능들이 포함되어 있습니다. 하지만, 너무 방대한 기능들로 인해 이런 기능이 있다는 것조차 알기 어렵습니다-_-; 솔직히 C# 바이블과 같은 책을 정독하기란 여간 어려운 일이 아닙니다. 아마도, 요즘 C#을 배운분들은 잘 사용하고 있을겁니다. 하지만, C# 1.1 부터 시작한 개발자중 몇몇은 아직도 모르는 기능들이 많을거라 생각되는군요. 대부분은 관련 커뮤니티나 세미나 또는 MSDN에서 꾸준히 정보를 검색하고 학습하고 있습니다^^

     

     

    nullable

    이 형식은 지정된 형식의 값뿐만 아니라 추가로 null 값을 처리할 수 있습니다. 그리고 2개의 읽기전용 공용 속성을 가지고 있습니다. 아래 예제를 통해 좀 더 알아보도록 하죠^^;

    Program.cs

    using static System.Console;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                int? i = 10; 
                double? d1 = 3.14; 
                bool? flag = null; 
                char? letter = 'a'; 
                int?[] arr = new int?[10]; 
                
                if (i.HasValue) 
                    WriteLine(i.Value);
                else 
                    WriteLine("Undefined"); 
                
                i = null; 
                
                if (i.HasValue) 
                    WriteLine(i.Value); 
                else 
                    WriteLine("Undefined"); 
                
                ReadKey();
            }
        }
    }

     

     

    결과는 아래와 같습니다. 

    DneLoyu.png

     

     

    null coalescing 연산자

    널 병합 연산자는 피연산자가 null이 아닐 경우 왼쪽 피연산자를 반환하고 null일 경우 오른쪽 피연산자를 반환합니다. 아래 예제를 통해 어떻게 동작하는지 알아봅시다.

    Program.cs

    using static System.Console;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            public static void Main()
            {
                string url = null; 
                string homepage = url ?? "http://www.ngmsoftware.com"; 
                
                WriteLine(homepage); 
                
                url = "http://www.google.com"; 
                homepage = url ?? "http://www.ngmaster.net"; 
                
                WriteLine(homepage); 
                ReadKey();
            }
        }
    }

     

     

    실행 해보면 아래와 같은 결과를 확인할 수 있습니다.

    EMxqrcb.png

     

     

    아래 예제는 Argument로 받은 파일명을 처리하는 방법을 보여줍니다.

    Program.cs

    using static System.Console;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                string fileName = string.Empty; 
                
                if (args?.Length == 0)
                {
                    WriteLine("ERROR: File missing. Use:\n\tfind.exe file:<filename>");
                }
                else
                {
                    if (args[0]?.ToLower().StartsWith("file:") ?? false)
                    {
                        fileName = args[0]?.Remove(0, 5);
                    }
                }
    
                WriteLine(fileName); 
                ReadKey();
            }
        }
    }

     

     

    위 코드를 비주얼 스튜디오에서 실행하려면 아래 그림처럼 디버그 탭에 명령줄 인수를 설정하세요.

    FqHaH9F.png

     

     

    다음 시간에...

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.