익명 형식(Visual Basic)

Visual Basic은 무명 형식을 지원하므로 데이터 형식에 대한 클래스 정의를 작성하지 않고도 개체를 만들 수 있습니다. 대신 컴파일러가 클래스를 생성합니다. 이 클래스는 사용할 수 있는 이름이 없고, Object(으)로부터 직접 상속되며, 개체를 선언할 때 지정하는 속성을 포함합니다. 데이터 형식의 이름은 지정되지 않으므로 무명 형식이라고 합니다.

다음 예제에서는 변수 product을(를) NamePrice의 두 가지 속성이 있는 무명 형식의 인스턴스로 선언하고 만듭니다.

' Variable product is an instance of a simple anonymous type.
Dim product = New With {Key .Name = "paperclips", .Price = 1.29}

쿼리 식은 무명 형식을 사용하여 쿼리에서 선택한 데이터 열을 결합합니다. 특정 쿼리에서 선택할 수 있는 열을 예측할 수 없으므로 결과의 형식을 미리 정의할 수 없습니다. 무명 형식을 사용하면 임의의 순서로 원하는 수의 열을 선택하는 쿼리를 작성할 수 있습니다. 컴파일러는 지정된 속성 및 지정된 순서와 일치하는 데이터 형식을 만듭니다.

다음 예제에서 products은(는) 각각에 많은 속성이 있는 제품 개체의 목록입니다. 변수 namePriceQuery은(는) 실행될 때 NamePrice 두 가지 속성이 있는 무명 형식의 인스턴스 컬렉션을 반환하는 쿼리의 정의를 갖고있습니다.

Dim namePriceQuery = From prod In products
                     Select prod.Name, prod.Price

변수 nameQuantityQuery은(는) 실행될 때 NameOnHand 두 가지 속성이 있는 무명 형식의 인스턴스 컬렉션을 반환하는 쿼리의 정의를 갖고있습니다.

Dim nameQuantityQuery = From prod In products
                        Select prod.Name, prod.OnHand

무명 형식에 대해 컴파일러에서 만든 코드에 대한 자세한 내용은 무명 형식 정의를 참조하세요.

주의

무명 형식의 이름은 컴파일러에서 생성되며 컴파일마다 다를 수 있습니다. 프로젝트가 다시 컴파일될 때 이름이 변경될 수 있으므로 코드에서 무명 형식의 이름을 사용하거나 이에 의존해서는 안 됩니다.

무명 형식 선언

무명 형식의 인스턴스 선언은 이니셜라이저 목록을 사용하여 형식의 속성을 지정합니다. 메서드 또는 이벤트와 같은 다른 클래스 요소가 아니라 무명 형식을 선언할 때만 속성을 지정할 수 있습니다. 다음 예제에서 product1은(는) NamePrice의 두 가지 속성을 갖는 무명 형식의 인스턴스입니다.

' Variable product1 is an instance of a simple anonymous type.
Dim product1 = New With {.Name = "paperclips", .Price = 1.29}
' -or-
' product2 is an instance of an anonymous type with key properties.
Dim product2 = New With {Key .Name = "paperclips", Key .Price = 1.29}

속성을 키 속성으로 지정하면 이를 사용하여 두 무명 형식 인스턴스의 동일성 여부를 비교할 수 있습니다. 그러나 키 속성의 값은 변경할 수 없습니다. 자세한 내용은 이 항목의 뒷부분에 있는 키 속성 섹션을 참조하세요.

무명 형식의 인스턴스를 선언하는 것은 개체 이니셜라이저를 사용하여 명명된 형식의 인스턴스를 선언하는 것과 같습니다.

' Variable product3 is an instance of a class named Product.
Dim product3 = New Product With {.Name = "paperclips", .Price = 1.29}

무명 형식 속성을 지정하는 다른 방법에 대한 자세한 내용은 방법: 무명 형식 선언에서 속성 이름 및 형식 유추를 참조하세요.

키 속성

키 속성은 다음과 같은 몇 가지 근본적인 면에서 키가 아닌 속성과 다릅니다.

  • 두 인스턴스가 동일한지 여부를 확인하기 위해 키 속성 값만 비교됩니다.

  • 키 속성의 값은 읽기 전용이며 변경할 수 없습니다.

  • 무명 형식에 대한 컴파일러 생성 해시 코드 알고리즘에는 키 속성 값만 포함됩니다.

Equality

무명 형식의 인스턴스는 동일한 무명 형식의 인스턴스인 경우에만 동일할 수 있습니다. 컴파일러는 두 인스턴스가 다음 조건을 충족하는 경우 동일한 형식의 인스턴스로 취급합니다.

  • 동일한 어셈블리에서 선언됩니다.

  • 해당 속성의 이름이 같고 유추된 형식이 동일하며 동일한 순서로 선언됩니다. 이름 비교는 대/소문자를 구분하지 않습니다.

  • 각각의 동일한 속성이 키 속성으로 표시됩니다.

  • 각 선언에서 하나 이상의 속성이 키 속성입니다.

키 속성이 없는 무명 형식의 인스턴스는 자신과만 동일합니다.

' prod1 and prod2 have no key values.
Dim prod1 = New With {.Name = "paperclips", .Price = 1.29}
Dim prod2 = New With {.Name = "paperclips", .Price = 1.29}

' The following line displays False, because prod1 and prod2 have no
' key properties.
Console.WriteLine(prod1.Equals(prod2))

' The following statement displays True because prod1 is equal to itself.
Console.WriteLine(prod1.Equals(prod1))

동일한 무명 형식의 두 인스턴스는 키 속성 값이 같으면 동일합니다. 다음 예제에서는 동일성을 테스트하는 방법을 보여 줍니다.

Dim prod3 = New With {Key .Name = "paperclips", Key .Price = 1.29}
Dim prod4 = New With {Key .Name = "paperclips", Key .Price = 1.29}
' The following line displays True, because prod3 and prod4 are
' instances of the same anonymous type, and the values of their
' key properties are equal.
Console.WriteLine(prod3.Equals(prod4))

Dim prod5 = New With {Key .Name = "paperclips", Key .Price = 1.29}
Dim prod6 = New With {Key .Name = "paperclips", Key .Price = 1.29,
                      .OnHand = 423}
' The following line displays False, because prod5 and prod6 do not 
' have the same properties.
Console.WriteLine(prod5.Equals(prod6))

Dim prod7 = New With {Key .Name = "paperclips", Key .Price = 1.29,
                      .OnHand = 24}
Dim prod8 = New With {Key .Name = "paperclips", Key .Price = 1.29,
                      .OnHand = 423}
' The following line displays True, because prod7 and prod8 are
' instances of the same anonymous type, and the values of their
' key properties are equal. The equality check does not compare the
' values of the non-key field.
Console.WriteLine(prod7.Equals(prod8))

읽기 전용 값

키 속성의 값은 변경할 수 없습니다. 예를 들어 이전 예제의 prod8에서는 NamePrice 필드가 read-only이나 OnHand을(를) 변경할 수 있습니다.

' The following statement will not compile, because Name is a key
' property and its value cannot be changed.
' prod8.Name = "clamps"

' OnHand is not a Key property. Its value can be changed.
prod8.OnHand = 22

쿼리 식의 무명 형식

쿼리 식에서 항상 무명 형식을 만들 필요는 없습니다. 가능하면 기존 형식을 사용하여 열 데이터를 저장합니다. 이 문제는 쿼리가 데이터 원본에서 전체 레코드를 반환하거나 각 레코드에서 하나의 필드만 반환할 때 발생합니다. 다음 코드 예제에서 customers은(는) Customer 클래스의 개체 컬렉션입니다. 클래스에는 많은 속성이 있으며 쿼리 결과에 하나 이상의 속성을 순서대로 포함할 수 있습니다. 처음 두 예제에서는 쿼리가 명명된 형식의 요소를 선택하기 때문에 무명 형식이 필요하지 않습니다.

  • cust.Name이(가) 문자열이므로 custs1은(는) 문자열 컬렉션을 포함합니다.

    Dim custs1 = From cust In customers
                 Select cust.Name
    
  • customers의 각 요소는 Customer 객체이고 쿼리에 의해 전체 요소가 선택되기 때문에 custs2은(는) Customer 객체의 컬렉션을 포함합니다.

    Dim custs2 = From cust In customers
                 Select cust
    

그러나 적절한 명명된 형식을 항상 사용할 수 있는 것은 아닙니다. 한 가지 용도로는 고객 이름과 주소를, 다른 용도로는 고객 ID 번호와 위치를, 세 번째 용도로는 고객 이름, 주소, 주문 내역을 선택할 수 있습니다. 무명 형식을 사용하면 결과를 저장할 새 명명된 형식을 먼저 선언하지 않고 순서에 관계없이 속성 조합을 선택할 수 있습니다. 대신 컴파일러는 속성의 각 컴파일에 대해 무명 형식을 만듭니다. 다음 쿼리는 customers의 각 Customer 개체에서 고객의 이름 및 ID 번호만 선택합니다. 따라서 컴파일러는 이러한 두 속성만 포함하는 무명 형식을 만듭니다.

Dim custs3 = From cust In customers
             Select cust.Name, cust.ID

무명 유형에 있는 속성의 이름과 데이터 유형은 모두 인수에서 Select, cust.Namecust.ID(으)로 가져옵니다. 쿼리에서 만든 무명 형식의 속성은 항상 키 속성입니다. 다음 For Each loop에서 custs3이(가) 실행되면 NameID 두 가지 키 속성이 있는 무명 형식의 인스턴스 컬렉션이 생성됩니다.

For Each selectedCust In custs3
    Console.WriteLine(selectedCust.ID & ": " & selectedCust.Name)
Next

custs3으(로) 표시되는 컬렉션의 요소는 강력한 형식이며, IntelliSense를 사용하여 사용 가능한 속성을 탐색하고 해당 형식을 확인할 수 있습니다.

자세한 내용은 Visual Basic의 LINQ 쿼리 소개를 참조하세요.

무명 형식을 사용할지 여부 결정

무명 클래스의 인스턴스로 개체를 만들기 전에 최상의 옵션인지 여부를 고려합니다. 예를 들어 관련 데이터를 포함하는 임시 객체를 만들고 싶지만 완전한 클래스에 포함될 수 있는 다른 필드와 메서드가 필요하지 않은 경우 무명 형식은 좋은 솔루션입니다. 무명 형식은 각 선언에 대해 다른 속성을 선택하거나 속성의 순서를 변경하려는 경우에도 편리합니다. 그러나 프로젝트에 동일한 속성을 가진 여러 개의 객체가 고정된 순서로 포함되어 있는 경우 클래스 생성자와 함께 명명된 형식을 사용하여 더 쉽게 선언할 수 있습니다. 예를 들어, 적절한 생성자를 사용하면 무명 유형의 인스턴스를 여러 개 선언하는 것보다 Product 클래스의 인스턴스를 여러 개 선언하는 것이 더 쉽습니다.

' Declaring instances of a named type.
Dim firstProd1 As New Product("paperclips", 1.29)
Dim secondProd1 As New Product("desklamp", 28.99)
Dim thirdProd1 As New Product("stapler", 5.09)

' Declaring instances of an anonymous type.
Dim firstProd2 = New With {Key .Name = "paperclips", Key .Price = 1.29}
Dim secondProd2 = New With {Key .Name = "desklamp", Key .Price = 28.99}
Dim thirdProd2 = New With {Key .Name = "stapler", Key .Price = 5.09}

명명된 형식의 또 다른 장점은 컴파일러가 실수로 속성 이름을 잘못 입력하는 것을 잡아낼 수 있다는 점입니다. 이전 예제에서 firstProd2, secondProd2thirdProd2은(는) 동일한 무명 형식의 인스턴스로 사용됩니다. 그러나 다음 방법 중 하나로 실수로 thirdProd2을(를) 선언하는 경우 해당 형식은 firstProd2secondProd2의 형식과 다릅니다.

' Dim thirdProd2 = New With {Key .Name = "stapler", Key .Price = 5.09}
' Dim thirdProd2 = New With {Key .Name = "stapler", Key .Price = "5.09"}
' Dim thirdProd2 = New With {Key .Name = "stapler", .Price = 5.09}

더 중요한 것은 무명 유형 사용에는 명명된 형식의 인스턴스에는 적용되지 않는 제한이 있다는 점입니다. firstProd2, secondProd2thirdProd2은(는) 동일한 무명 형식의 인스턴스입니다. 그러나 공유 무명 형식의 이름은 사용할 수 없으며 코드에서 형식 이름이 예상되는 위치에 표시될 수 없습니다. 예를 들어 무명 형식을 사용하여 메서드 시그니처를 정의하거나, 다른 변수 또는 필드를 선언하거나, 형식 선언에서 선언할 수 없습니다. 따라서 메서드 간에 정보를 공유해야 하는 경우에는 무명 형식이 적절하지 않습니다.

무명 형식 정의

무명 형식의 인스턴스 선언에 대한 응답으로 컴파일러는 지정된 속성을 포함하는 새 클래스 정의를 만듭니다.

무명 유형에 하나 이상의 키 속성이 포함된 경우 이 정의는 Object에서 상속된 세 개의 멤버 Equals, GetHashCodeToString을(를) 재정의합니다. 동일성을 테스트하고 해시 코드 값을 결정하기 위해 생성된 코드는 키 속성만 고려합니다. 무명 형식에 키 속성이 없는 경우 ToString만 재정의됩니다. 무명 형식의 명시적으로 명명된 속성은 생성된 메서드와 충돌할 수 없습니다. 즉, .Equals, .GetHashCode 또는 .ToString을(를) 사용하여 속성 이름을 지정할 수 없습니다.

하나 이상의 키 속성이 있는 무명 형식 정의도 System.IEquatable<T> 인터페이스를 구현합니다. 여기서 T은(는) 무명명 형식의 형식입니다.

컴파일러에서 만든 코드 및 재정의된 메서드의 기능에 대한 자세한 내용은 익명 형식 정의를 참조하세요.

참고 항목