본문 바로가기
C#

[C#] 익명 형식(Anonymous Type)과 덕 타이핑(Duck Typing), 개체 이니셜라이저, nameof 연산자

by RucA 2024. 4. 30.
728x90
반응형

개체 이니셜라이져는 속성을 통해 개체 값을 설정하는 편의기능을 제공한다. 또한 개체 이니셜라이져와 new 연산자를 함께 사용하는 것으로 익명 형식을 만들 수 있다. 또한 재미있는 덕 타이핑이라는 주제와 유용한 nameof 연산자까지 다루도록 하겠다. 덕 타이핑과 nameof는 속성에 국한된 개념은 아니지만, 개념 설명 후 속성에 관련지어 정리하겠다.

 

 

개체 이니셜라이저 (Object Initializer)


개체 이니셜라이저를 사용해 단일 명령문으로 개체의 모든 엑세스 가능한 필드나 속성에 값을 추가할 수 있다.

 

  • 개체 이니셜라이저를 사용한 개체 속성 초기화
using System;

class InitPractice
{
    public string Name { get; set; }
    public int Age { get; set; }
    
    static void Main()
    {
        //개체 이니셜라이저를 사용해 개체 초기화
        InitPractice init = new InitPractice() { Name = "김밥", Age = 25 };
        Console.WriteLine($"{init.Name} {init.Age}");
    }
}

 

  • 개체 속성 초기화하는 방법 총정리
using System;

class InitPractice
{
    public string Name { get; set; }
    public int Age { get; set; }

    public InitPractice()
    {
    }

    public InitPractice(string name, int age)
    {
        Name = name;
        Age = age;
    }
    
    static void Main()
    {
        //속성 접근자 사용
        InitPractice init1 = new InitPractice();
        init1.Name = "속성 접근자";
        init1.Age = 25;
        
        //생성자 사용
        InitPractice init2 = new InitPractice("생성자", 25);
        
        //개체 이니셜라이저를 사용해 개체 초기화
        InitPractice init3 = new InitPractice() { Name = "개체 이니셜라이저", Age = 25 };
    }
}

 

 

익명 형식 (Anonymous Type)


무명 형식이라고도 한다. 익명 형식을 사용해 명시적으로 형식을 정의하지 않고 읽기 전용 속성을 가진 개체를 생성할 수 있다. 각 속성의 형식은 컴파일러에 의해 유추(타입 추론)된다. 주로 쿼리 식의 select 절에 사용된다.

 

  • 익명 형식 사용법
using System;

class AnonymousPractice
{
    static void Main()
    {
        //익명 형식 사용
        var unknown = new { Name = "anonymous", Age = -1 };
        
        Console.WriteLine($"{unknown.Name} {unknown.Age}");
        
        //익명 형식은 배열 형식으로도 사용 가능
        var unknowns = new[]
        {
            new { Name = "whoAmI", Age = -2 },
            new { Name = "IdontKnow", Age = -3 }
        };
    }
}

 

 

덕 타이핑 (Duck Typing)


덕 타이핑은 동적 타이핑의 한 종류로, 객체의 변수 및 메소드의 집합이 개체의 타입을 결정하는 것을 의미한다. 오리처럼 꽥꽥거리고 깃털이 있으며 수영할 수 있는 개체는 모두 오리로 유추하는 것이다. 이는 익명 형식의 타입 추론과 연결지어 설명될 수 있다.

 

  • 익명 형식 + 덕 타이핑 : 한번 생성한 익명 형식의 개체에 다른 익명 형식 재할당 시 형태, 속성, 형식이 동일해야 한다.
using System;

class AnonymousPractice
{
    static void Main()
    {
        //익명 형식으로 duck 개체 생성
        var duck = new { Name = "donardDuck", Age = 10 };
        
        //생성한 duck 개체에 재할당 시 덕 타이핑에 맞춰 받는다.
        duck = new { Name = "TrumpDuck", Age = 30 };
        
        Console.WriteLine($"{duck.Name} {duck.Age}");
        
        //아래 주석 처리된 코드처럼 형태, 속성, 형식이 다른 경우 예외처리된다.
        //duck = new { Name = "TrumpDuck"};             //형태가 다름(부족)
        //duck = new { Name = "TrumpDuck", Age = 30, Email = "abc@dfe.com" }; //형태가 다름(과다)
        //duck = new { NickName = "Hello", Age = 30 };  //속성이 다름
        //duck = new { Name = 10, Age = 10 };           //형식이 다름
    }
}

 

 

nameof 연산자


C# 6.0 버전부터 제공되는 연산자로, 속성과 메서드 등의 이름을 가져올 수 있다. 주로 이를 활용해 식별자 또는 변수 이름에 대한 리팩터링, 이름 변경 등에 사용한다.

 

  • nameof 연산자 : 속성 이름 가져오기
using System;

class NameOfPractice
{
    //자동 구현 속성
    public string Name { get; set; }
    
    static void Main()
    {
        NameOfPractice n = new NameOfPractice();
        
        //nameof 연산자 사용해 속성 이름 가져오기
        Console.WriteLine(nameof(n.Name));
    }
}
//출력 : Name

 

  • nameof 연산자 : 메서드 이름 가져오기
using System;

class NameOfPractice
{
    //메소드
    static void MethodNameOf()
    {
    }
    
    static void Main()
    {
        //nameof 연산자 사용해 속성 이름 가져오기
        Console.WriteLine(nameof(MethodNameOf));
    }
}
//출력 : MethodNameOf

 

물론 개발자가 직접 문자열로 입력해도 되지만, 오타가 발생할 수 있으며 안전성과 생산성을 위해 nameof 연산자를 활용하는 것이 좋을 듯하다. 특히 익명 형식의 경우 재할당을 위해서는 덕 타이핑을 생각하면서 해야 하는데, nameof 연산자를 활용하는 것으로 더 정교한 구현이 가능할 것이라 생각한다.

728x90
반응형