무명 형식

익명 형식을 사용하면 먼저 명시적으로 형식을 정의할 필요 없이 읽기 전용 속성 집합을 단일 개체로 편리하게 캡슐화할 수 있습니다. 형식 이름은 컴파일러에 의해 생성되며 소스 코드 수준에서 사용할 수 없습니다. 각 속성의 형식은 컴파일러에서 유추합니다.

new 연산자를 개체 이니셜라이저와 함께 사용하여 무명 형식을 만듭니다. 개체 이니셜라이저에 대한 자세한 내용은 개체 및 컬렉션 이니셜라이저를 참조하세요.

다음 예제에서는 AmountMessage라는 두 속성으로 초기화된 익명 형식을 보여 줍니다.

var v = new { Amount = 108, Message = "Hello" };

// Rest the mouse pointer over v.Amount and v.Message in the following
// statement to verify that their inferred types are int and string.
Console.WriteLine(v.Amount + v.Message);

일반적으로 무명 형식은 소스 시퀀스에 있는 각 개체의 속성 하위 집합을 반환하기 위해 쿼리 식의 select 절에 사용됩니다. 쿼리에 대한 자세한 내용은 C#의 LINQ를 참조하세요.

익명 형식은 하나 이상의 public 읽기 전용 속성을 포함합니다. 메서드 또는 이벤트와 같은 다른 종류의 클래스 멤버는 유효하지 않습니다. 속성을 초기화하는 데 사용되는 식은 null, 익명 함수 또는 포인터 형식일 수 없습니다.

가장 일반적인 시나리오는 다른 형식의 속성으로 익명 형식을 초기화하는 것입니다. 다음 예제에서는 Product라는 클래스가 있다고 가정합니다. Product 클래스에는 ColorPrice 속성뿐만 아니라 관심 없는 다른 속성도 포함되어 있습니다. products 변수는 Product 개체의 컬렉션입니다. 익명 형식 선언은 new 키워드로 시작합니다. 선언에서는 Product의 두 속성만 사용하는 새 형식을 초기화합니다. 무명 형식을 사용하면 더 적은 양의 데이터가 쿼리에 반환됩니다.

무명 형식에 멤버 이름을 지정하지 않으면 컴파일러가 무명 형식 멤버에 해당 멤버를 초기화하는 데 사용되는 속성과 동일한 이름을 제공합니다. 앞의 예제에 표시된 것처럼, 식으로 초기화되는 속성의 이름을 제공합니다. 다음 예제에서 익명 형식의 속성 이름은 ColorPrice입니다.

var productQuery =
    from prod in products
    select new { prod.Color, prod.Price };

foreach (var v in productQuery)
{
    Console.WriteLine("Color={0}, Price={1}", v.Color, v.Price);
}

.NET 스타일 규칙 IDE0037을 사용하여 유추된 멤버 이름 또는 명시적 멤버 이름 중 어느 것이 선호되는지를 적용할 수 있습니다.

클래스, 구조체 또는 다른 무명 형식과 같은 다른 형식의 개체별로 필드를 정의할 수도 있습니다. 이 작업은 이미 인스턴스화된 사용자 정의 형식을 사용하여 두 개의 무명 형식이 만들어지는 다음 예제와 마찬가지로 이 개체를 보유하는 변수를 사용하여 수행됩니다. 두 경우 모두 무명 형식 shipmentshipmentWithBonusproduct 필드는 각 필드의 기본값을 포함하는 Product 형식이 됩니다. 그리고 bonus 필드는 컴파일러에서 만든 무명 형식이 됩니다.

var product = new Product();
var bonus = new { note = "You won!" };
var shipment = new { address = "Nowhere St.", product };
var shipmentWithBonus = new { address = "Somewhere St.", product, bonus };

일반적으로 무명 형식을 사용하여 변수를 초기화할 때는 var을 사용하여 변수를 암시적 형식 지역 변수로 선언합니다. 컴파일러만 익명 형식의 기본 이름에 액세스할 수 있으므로 변수 선언에는 형식 이름을 지정할 수 없습니다. var에 대한 자세한 내용은 암시적 형식 지역 변수를 참조하세요.

다음 예제에 표시된 것처럼, 암시적으로 형식화된 지역 변수와 암시적으로 형식화된 배열을 결합하여 익명으로 형식화된 요소의 배열을 만들 수 있습니다.

var anonArray = new[] { new { name = "apple", diam = 4 }, new { name = "grape", diam = 1 }};

무명 형식은 object에서 직접 파생되고 object를 제외한 어떠한 형식으로도 캐스팅될 수 없는 class 형식입니다. 컴파일러는 애플리케이션에서 해당 익명 형식에 액세스할 수 없더라도 각 익명 형식의 이름을 제공합니다. 공용 언어 런타임의 관점에서 익명 형식은 다른 참조 형식과 다를 바가 없습니다.

어셈블리에서 둘 이상의 익명 개체 이니셜라이저가 순서와 이름 및 형식이 동일한 속성의 시퀀스를 지정하는 경우 컴파일러는 개체를 동일한 형식의 인스턴스로 처리합니다. 이러한 개체는 컴파일러에서 생성된 동일한 형식 정보를 공유합니다.

무명 형식은 with 식 형태로 비파괴적 변경을 지원합니다. 이로 인해 하나 이상의 속성에 새 값이 있는 무명 형식의 새 인스턴스를 만들 수 있습니다.

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

익명 형식을 가지고 있으므로 필드, 속성, 이벤트 또는 메서드의 반환 형식은 선언할 수 없습니다. 마찬가지로, 익명 형식을 가지고 있으므로 메서드, 속성, 생성자 또는 인덱서의 정식 매개 변수는 선언할 수 없습니다. 무명 형식이나 무명 형식이 포함된 컬렉션을 메서드에 인수로 전달하려면 매개 변수를 object 형식으로 선언하면 됩니다. 그러나 무명 형식에 object를 사용하면 강력한 형식화의 목적이 무효화됩니다. 쿼리 결과를 저장하거나 메서드 경계 외부로 전달해야 하는 경우 익명 형식 대신 일반적인 명명된 구조체 또는 클래스 사용을 고려하세요.

익명 형식에 대한 EqualsGetHashCode 메서드는 속성의 EqualsGetHashCode 메서드 측면에서 정의되므로 동일한 익명 형식의 두 인스턴스는 해당 속성이 모두 동일한 경우에만 동일합니다.

참고 항목

무명 형식의 접근성 수준internal이므로 서로 다른 어셈블리에 정의된 두 무명 형식은 동일한 형식이 아닙니다. 따라서 무명 형식의 인스턴스는 모든 속성이 같은 경우에도 서로 다른 어셈블리에 정의된 경우 서로 같을 수 없습니다.

무명 형식은 ToString 메서드를 재정의하여 중괄호로 둘러싸인 모든 속성의 이름과 ToString 출력을 연결합니다.

var v = new { Title = "Hello", Age = 24 };

Console.WriteLine(v.ToString()); // "{ Title = Hello, Age = 24 }"