Notice
Recent Posts
Recent Comments
Link
관리 메뉴

nomad-programmer

[Programming/C#] var : 데이터 형식을 알아서 파악하는 C#컴파일러 본문

Programming/C#

[Programming/C#] var : 데이터 형식을 알아서 파악하는 C#컴파일러

scii 2020. 9. 6. 15:10

C#은 변수나 상수에 대해 꼼꼼히 형식 검사를 진행하는 강력한 형식의 언어이다. 강력한 형식 검사는 프로그래머의 실수르 줄여 주는 장점이 있다. 의도치 않은 형식의 데이터를 읽거나 할당하는 일을 막아준다.
예를 들어 원래는 정수 형식의 데이터를 담기 위해 n이라는 변수를 선언했는데, 다른 프로그래머가 이 코드를 물려받아서는 중간에 문자열 형식을 담아 쓰려고 할 수 있다. 약한 형식 검사는 이런 문제를 막을 수 없지만, 강력한 형식 검사는 이 문제를 컴파일 타임에 찾아내 드러내 준다.

하지만 약한 형식 검사가 단점만 있는 것은 아니다. 코드를 작성하는 단계에서는 약한 형식 검사가 더 편리하다. 귀찮게 int, long, uint, ulong 등과 같은 형식을 외울 필요 없이 일단 변수를 선언해서 데이터를 할당하면, 컴파일러나 인터프리터가 해당 변수에 담는 데이터를 보고 자동으로 형식을 지정해준다.

C#은 강력한 형식 검사를 하는 언어이지만, var 키워드를 통해 약한 형식 검사를 하는 언어의 편리함도 지원한다. int, string 같은 명시적 형식 대신 var를 사용해서 변수를 선언하면 컴파일러가 자동으로 해당 변수의 형식을 지정해준다. 단, var 키워드를 이용해서 변수를 선언하려면 반드시 선언과 동시에 초기화를 해줘야 한다. 그래야 컴파일러가 그 데이터를 보고 형식을 추론할 수 있기 때문이다. 

var는 지역 변수로만 사용할 수 있다.
클래스의 필드를 선언할 때는 명시적 형식을 선언해야 한다. 그 이유는 var 키워드로 필드를 선언하면 컴파일러가 무슨 형식인지 파악할 길이 없기 때문이다.
using System;

namespace CSharpExam
{
    class VarExample
    {
        static int Main(string[] args)
        {
            var a = 20;
            Console.WriteLine("Type: {0}, Value: {1}", a.GetType(), a);

            var b = 3.141592f;
            Console.WriteLine("Type: {0}, Value: {1}", b.GetType(), b);

            var c = "Hello World!";
            Console.WriteLine("Type: {0}, Value: {1}", c.GetType(), c);

            var d = new int[] { 10, 20, 30 };
            Console.WriteLine("Type: {0}", d);
            foreach (var e in d)
            {
                Console.Write($"{e} ");
            }
            Console.WriteLine();

            return 0;
        }
    }
}

var 형식과 object 형식의 차이점

object a = 20;
object b = 3.14f;
object c = "Hello, World!";

object형식으로도 위와 같은 코드를 작성할 수 있다.
허나 obejct형식은 object형식을 뿐이다. 예를 들어 위 코드 중 object a = 20;이 컴파일돼서 실행되면 CLR은 20을 박싱해서 힙에 넣어 놓고 a가 Heap메모리 영역을 가리키도록 만들 것이다. (C/C++의 포인터 처럼)
하지만 var a = 20;은 컴파일 시점에 컴파일러가 a에 적합한 데이터 형식을 파악해서 int a = 20;으로 바꿔 컴파일한다. 이를테면 치환자같은 것이다.
CLR이 해당 코드를 실행할 때는 a가 var로 선언되었는지조차 눈치채지 못하고 int형식의 객체 a에 20을 담아 Stack메모리 공간에 올린다.

Comments