Visual Basic은 익명 형식을 지원하므로 데이터 형식에 대한 클래스 정의를 작성하지 않고도 개체를 만들 수 있습니다. 대신 컴파일러에서 클래스를 생성합니다. 클래스에는 사용할 수 있는 이름이 없고, 개체에서 Object직접 상속되며, 개체 선언에 지정한 속성이 포함됩니다. 데이터 형식의 이름은 지정되지 않으므로 익명 형식이라고 합니다.
다음 예제에서는 두 개의 속성을 product 포함하는 무명 형식의 인스턴스로 변수 Name 를 선언하고 Price만듭니다.
' Variable product is an instance of a simple anonymous type.
Dim product = New With {Key .Name = "paperclips", .Price = 1.29}
쿼리 식은 익명 형식을 사용하여 쿼리에서 선택한 데이터 열을 결합합니다. 특정 쿼리에서 선택할 수 있는 열을 예측할 수 없으므로 결과의 형식을 미리 정의할 수 없습니다. 익명 형식을 사용하면 임의의 순서로 원하는 수의 열을 선택하는 쿼리를 작성할 수 있습니다. 컴파일러는 지정된 속성 및 지정된 순서와 일치하는 데이터 형식을 만듭니다.
다음 예제 products 에서는 각각 많은 속성이 있는 제품 개체의 목록입니다. 변수 namePriceQuery는 실행될 때 속성 Name과 Price를 가진 익명 형식의 인스턴스 컬렉션을 반환하는 쿼리의 정의를 보유합니다.
Dim namePriceQuery = From prod In products
Select prod.Name, prod.Price
변수 nameQuantityQuery는 실행될 때 속성 Name과 OnHand를 가진 익명 형식의 인스턴스 컬렉션을 반환하는 쿼리의 정의를 보유합니다.
Dim nameQuantityQuery = From prod In products
Select prod.Name, prod.OnHand
익명 형식에 대해 컴파일러에서 만든 코드에 대한 자세한 내용은 익명 형식 정의를 참조하세요.
주의
익명 형식의 이름은 컴파일러가 생성되며 컴파일마다 다를 수 있습니다. 프로젝트를 다시 컴파일할 때 이름이 변경될 수 있으므로 코드에서 익명 형식의 이름을 사용하거나 사용하지 않아야 합니다.
익명 형식 선언
익명 형식의 인스턴스 선언은 이니셜라이저 목록을 사용하여 형식의 속성을 지정합니다. 메서드 또는 이벤트와 같은 다른 클래스 요소가 아니라 익명 형식을 선언할 때만 속성을 지정할 수 있습니다. 다음 예제에서는, product1이 두 개의 속성 Name과 Price를 가진 익명 형식의 인스턴스입니다.
' 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}
익명 형식 속성을 지정하는 다른 방법에 대한 자세한 내용은 방법: 익명 형식 선언에서 속성 이름 및 형식 유추를 참조하세요.
키 속성
키 속성은 다음과 같은 몇 가지 기본적인 방법으로 키가 아닌 속성과 다릅니다.
두 인스턴스가 같은지 여부를 확인하기 위해 키 속성 값만 비교됩니다.
키 속성의 값은 읽기 전용이며 변경할 수 없습니다.
익명 형식에 대한 컴파일러 생성 해시 코드 알고리즘에는 키 속성 값만 포함됩니다.
평등
익명 형식의 인스턴스는 동일한 익명 형식의 인스턴스인 경우에만 같을 수 있습니다. 컴파일러는 다음 조건을 충족하는 경우 두 인스턴스를 동일한 형식의 인스턴스로 처리합니다.
동일한 어셈블리에서 선언됩니다.
해당 속성은 이름이 같고 유추된 형식이 동일하며 동일한 순서로 선언됩니다. 이름 비교는 대/소문자를 구분하지 않습니다.
각 속성의 동일한 속성이 키 속성으로 표시됩니다.
각 선언에서 하나 이상의 속성이 키 속성입니다.
키 속성이 없는 익명 형식의 인스턴스는 자체와만 같습니다.
' 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))
Read-Only 값
키 속성의 값은 변경할 수 없습니다. 예를 들어 이전 예제 prod8 에서는 Name 필드와 Price 필드가 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 클래스의 객체 컬렉션입니다. 클래스에는 많은 속성이 있으며 쿼리 결과에 하나 이상의 속성을 순서대로 포함할 수 있습니다. 처음 두 예제에서는 쿼리가 명명된 형식의 요소를 선택하기 때문에 익명 형식이 필요하지 않습니다.
custs1에는 문자열이 있으므로cust.Name문자열 컬렉션이 포함됩니다.Dim custs1 = From cust In customers Select cust.Namecusts2은Customer개체의 컬렉션을 포함합니다. 각customers의 요소가Customer개체이기 때문에 전체 요소가 쿼리로 선택됩니다.Dim custs2 = From cust In customers Select cust
그러나 적절한 명명된 형식을 항상 사용할 수 있는 것은 아닙니다. 한 용도로 고객 이름 및 주소, 다른 용도의 고객 ID 번호 및 위치, 고객 이름, 주소 및 주문 기록을 세 번째 용도로 선택할 수 있습니다. 무명 형식을 사용하면 결과를 저장할 새 명명된 형식을 먼저 선언하지 않고 순서에 관계없이 속성 조합을 선택할 수 있습니다. 대신 컴파일러는 속성의 각 컴파일에 대해 익명 형식을 만듭니다. 다음 쿼리는 에 있는 각 Customer 개체 customers에서 고객의 이름 및 ID 번호만 선택합니다. 따라서 컴파일러는 이러한 두 속성만 포함하는 익명 형식을 만듭니다.
Dim custs3 = From cust In customers
Select cust.Name, cust.ID
익명 형식의 속성의 이름과 데이터 형식은 인수 Select, cust.Name 및 cust.ID에서 가져옵니다. 쿼리에서 만든 익명 형식의 속성은 항상 키 속성입니다.
custs3 다음 For Each 루프에서 실행될 때, 결과는 두 개의 키 속성 Name 및 ID을 가진 익명 형식의 인스턴스 컬렉션입니다.
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에서 , secondProd2및 thirdProd2 동일한 익명 형식의 인스턴스로 사용됩니다. 그러나 다음 방법 중 하나로 thirdProd2을 실수로 선언할 경우, 그 형식은 firstProd2 및 secondProd2의 형식과 다릅니다.
' 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, secondProd2및 thirdProd2 동일한 익명 형식의 인스턴스입니다. 그러나 공유 익명 형식의 이름은 사용할 수 없으며 코드에서 형식 이름이 필요한 위치에 표시할 수 없습니다. 예를 들어 익명 형식을 사용하여 메서드 시그니처를 정의하거나, 다른 변수 또는 필드를 선언하거나, 형식 선언에서 선언할 수 없습니다. 따라서 메서드 간에 정보를 공유해야 하는 경우에는 익명 형식이 적절하지 않습니다.
익명 형식 정의
익명 형식의 인스턴스 선언에 대한 응답으로 컴파일러는 지정된 속성을 포함하는 새 클래스 정의를 만듭니다.
무명 형식에 하나 이상의 키 속성이 포함된 경우 정의는 Object, Equals, GetHashCode에서 상속된 세 개의 멤버를 재정의합니다. 같음을 테스트하고 해시 코드 값을 결정하기 위해 생성된 코드는 키 속성만 고려합니다. 무명 형식에 키 속성이 없으면 ToString가 재정의됩니다. 익명 형식의 명시적으로 명명된 속성은 생성된 메서드와 충돌할 수 없습니다. 즉, .Equals, .GetHashCode, 또는 .ToString를 속성 이름으로 사용할 수 없습니다.
하나 이상의 키 속성이 포함된 익명 형식 정의는 System.IEquatable<T> 유형으로, T 인터페이스도 구현합니다.
컴파일러에서 만든 코드 및 재정의된 메서드의 기능에 대한 자세한 내용은 익명 형식 정의를 참조하세요.
참고하십시오
.NET