본문 바로가기
C#

C#] Anonymous Type(무명 형식) 정의, 사용법, Dynamic Type과 비교

by Fastlane 2022. 6. 28.
728x90
반응형

출처 : https://code-maze.com/anonymous-types-csharp/

 Anonymous Type이란?

이름이 없는 클래스레벨 참조형식이다. 형식지정 없이 object를 초기화할 수 있다. 

 

한개 이상의 public read-only properties를 갖는다. compiler가 할당값에 따라 peroperty의 type을 결정하고, object의 name도 생성한다. 

 

임시 데이터의 저장을 위해 주로 사용된다. object전체를 anonymous type으로 할당하는 대신, 필요한 properties만 할당할 수 있고, 이는 LINQ expression에서 유용하게 사용된다. 

 

Anonymous Type의 사용법

Anonymous Type은 var와 new keyword와 함께 object initializer로 정의된다. Propetries는 null value, class method, event를 가질 수 없으며, 수정되지 않는다. 

var employee = new
{
    Id = 001,
    FirstName = "John",
    LastName = "Doe",
    Department = "Marketing",
    FullTime = false,
    HourlyPay = 35.75
};
Console.WriteLine($"Id: {employee.Id}");                  // Id: 1
Console.WriteLine($"First Name: {employee.FirstName}");   // First Name: John  
Console.WriteLine($"Last Name: {employee.LastName}");     // Last Name: Doe
Console.WriteLine($"Department: {employee.Department}");  // Department: Marketing
Console.WriteLine($"Full Time: {employee.FullTime}");     // Full Time: False
Console.WriteLine($"Hourly Pay: {employee.HourlyPay}");   // Hourly Pay: 35.75

regular object와 동일하게 anonymous type의 properties에 접근할 수 있다. 

compiler가 type을 결정하기 때문에, 우리는 Object.GetType() method를 결정된 type을 가져오는데 사용할 수 있다. 

Console.WriteLine($"Id Type: {employee.Id.GetType()}");                  // Id Type: int
Console.WriteLine($"First Name Type: {employee.FirstName.GetType()}");   // First Name Type: string
Console.WriteLine($"Last Name Type: {employee.LastName.GetType()}");     // Last Name Type: string
Console.WriteLine($"Department Type: {employee.Department.GetType()}");  // Department Type: string
Console.WriteLine($"Full Time Type: {employee.FullTime.GetType()}");     // Full Time Type: bool
Console.WriteLine($"Hourly Pay Type: {employee.HourlyPay.GetType()}");   // Hourly Pay Type: double

Nested Anonymous Type

Anonymous Type의 properties내부에 Anonymout Type을 중첩할 수 있다. 

var employee = new
{
    Id = 0002,
    FirstName = "Jane",
    LastName = "Doe",
    Department = "Accounting",
    OfficeAddress = new { Street = "123 Green St.", 
                          City = "Atlanta", 
                          State = "Georgia", 
                          Country = "USA" }
};

Console.WriteLine($"Employee Office Location: {employee.OfficeAddress.City}");  // Employee Office Location: Atlanta

Array of Anonymous Type

var employees = new[]
{
    new { Id = 001, FirstName = "John", LastName = "Doe", Department = "Marketing" },
    new { Id = 002, FirstName = "Jane", LastName = "Doe", Department = "Accounting" },
    new { Id = 003, FirstName = "Bob", LastName = "Smith", Department = "Human Resources" }
};

foreach (var emp in employees)
{
    Console.WriteLine($"Id: {emp.Id} Name: {emp.FirstName} {emp.LastName}");
}
// Id: 1 Name: John Doe
// Id: 2 Name: Jane Doe
// Id: 3 Name: Bob Smith

Anonymous Types in LINQ Expressions

필요한 properties만 가져올 수 있기 때문에, anonymous type은 LINQ expression에서 유용하다. 메모리 절약과, 불필요한 code를 피할 수 있다. 

var employeesFromList = from e in EmployeeList
               select new { Id = e.Id, Name = $"{e.FirstName} {e.LastName}" };
foreach (var emp in employeesFromList)
    Console.WriteLine($"Id: {emp.Id} Name: {emp.Name}");

Anonymous VS Dynamic Types

Anonymous type과 Dynamic type은 매우 유사하다. dynamic type이 dynamic keyword를 사용하는 것을 제외하고 정의하는 방법도 유사하다. 

dynamic employee = new
{
    Id = 001,
    FirstName = "John",
    LastName = "Doe",
};
Console.WriteLine($"Id: {employee.Id}");                               // Id: 1
Console.WriteLine($"Name: {employee.FirstName} {employee.LastName}");  // Name: John Doe

다른점은 anonymous type은 compiler가 체크하고, dynamic type은 runtime이 체크한다. 

anonymous type에 value를 assingn하면 data type이 고정되고 이후로 변경하려고 하면 에러가 발생한다. 

하지만, dynamic type은 런타임에 에러만 발생하지 않는다면, 몇번이고 data type을 변경할 수 있다. 

with expression

 Anonymous type은 C# 10부터 with expression형식으로 non-destructive mutation을 지원한다. 

var apple = new { Item = "apples", Price = 1.35 };
var onSale = apple with { Price = 0.79 };
Console.WriteLine(apple);
Console.WriteLine(onSale);

 

728x90
반응형

댓글