Практическое руководство. Выведение имен свойств и типов в объявлениях анонимных типов (Visual Basic)

Анонимные типы не предоставляют механизм для прямого указания типов данных для свойств. Типы всех свойств определяются посредством вывода. В следующем примере типы Name и Price выводятся напрямую из значений, которые используются для их инициализации.

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

Анонимные типы также могут выводить имена и типы свойств из других источников. В последующих разделах представлен список ситуаций, где вывод возможен, и примеры обратных ситуаций.

Успешный вывод

Анонимные типы могут выводить имена и типы свойств из следующих источников.

  • Из имен переменных. Анонимный тип anonProduct будет иметь два свойства: productName и productPrice. Их типами данных будут типы исходных переменных, String и Doubleсоответственно.

    Dim productName As String = "paperclips"
    Dim productPrice As Double = 1.29
    Dim anonProduct = New With {Key productName, Key productPrice}
    
    ' To create uppercase variable names for the new properties,
    ' assign variables productName and productPrice to uppercase identifiers.
    Dim anonProduct1 = New With {Key .Name = productName, Key .Price = productPrice}
    
  • Из имен свойств или полей других объектов. Например, рассмотрим объект car типа CarClass , включающий свойства Name и ID . Чтобы создать новый экземпляр анонимного типа car1со свойствами Name и ID , которые инициализируются значениями из объекта car , можно написать следующее.

    Dim car1 = New With {Key car.Name, Key car.ID}
    

    Предыдущее объявление эквивалентно большей строке кода, определяющей анонимный тип car2.

    Dim car2 = New With {Key .Name = car.Name, Key .ID = car.ID}
    
  • Из имен элементов XML

    Dim books = <Books>
                    <Book Author="Jesper Aaberg">
                        Advanced Programming Methods
                    </Book>
                </Books>
    Dim anon = New With {books...<Book>}
    

    Результирующий тип для anon будет иметь одно свойство Bookc типом IEnumerable(XElement).

  • Из функции, которая не имеет параметров, например SomeFunction в следующем примере.

    Dim sc As New SomeClass
    Dim anon1 = New With {Key sc.SomeFunction()}
    

    Переменная anon2 в следующем коде является анонимным типом, который имеет одно свойство: знак с именем First. Этот код будет отображать букву E — букву, которая возвращена функцией First.

    Dim aString As String = "Example String"
    Dim anon2 = New With {Key aString.First()}
    ' The variable anon2 has one property, First.
    Console.WriteLine(anon2.First)
    

Неудачный вывод

Вывод имени завершится сбоем во многих случаях, в том числе в следующих.

  • Вывод является производным от вызова метода, конструктора или параметризованного свойства, для которого требуются аргументы. Предыдущее объявление anon1 завершается сбоем, если someFunction имеет один или несколько аргументов.

    ' Not valid.
    ' Dim anon3 = New With {Key sc.someFunction(someArg)}
    

    Проблема решается путем назначения новому имени свойства.

    ' Valid.
    Dim anon4 = New With {Key .FunResult = sc.someFunction(someArg)}
    
  • Вывод является производным от сложного выражения.

    Dim aString As String = "Act "
    ' Not valid.
    ' Dim label = New With {Key aString & "IV"}
    

    Ошибку можно устранить, назначив результат выражения для имени свойства.

    ' Valid.
    Dim label1 = New With {Key .someLabel = aString & "IV"}
    
  • Вывод нескольких свойств создает два или более свойств с одинаковым именем. Возвращаясь к объявлениям в предыдущих примерах, невозможно указывать product.Name и car1.Name в качестве свойств для одного анонимного типа. Это связано с тем, что выводимый идентификатор для каждого из них будет Name.

    ' Not valid.
    ' Dim anon5 = New With {Key product.Name, Key car1.Name}
    

    Проблему можно решить, назначив значения уникальным именам свойств.

    ' Valid.
    Dim anon6 = New With {Key .ProductName = product.Name, Key .CarName = car1.Name}
    

    Обратите внимание, что изменение регистра (изменение прописных букв на строчные и наоборот) не делает имя уникальным.

    Dim price = 0
    ' Not valid, because Price and price are the same name.
    ' Dim anon7 = New With {Key product.Price, Key price}
    
  • Исходные тип и значение одного свойства зависят от другого свойства, которое еще не установлено. Например, .IDName = .LastName не является допустимым в объявлении анонимного типа, если только .LastName уже не инициализирован.

    ' Not valid.
    ' Dim anon8 = New With {Key .IDName = .LastName, Key .LastName = "Jones"}
    

    В этом примере проблему можно устранить, изменив порядок, в котором объявлены свойства, на обратный.

    ' Valid.
    Dim anon9 = New With {Key .LastName = "Jones", Key .IDName = .LastName}
    
  • Имя свойства анонимного типа совпадает с именем элемента Object. Например, следующее объявление завершится сбоем, так как Equals — это метод Object.

    ' Not valid.
    ' Dim relationsLabels1 = New With {Key .Equals = "equals", Key .Greater = _
    '                       "greater than", Key .Less = "less than"}
    

    Проблему можно устранить, изменив имя свойства:

    ' Valid 
    Dim relationsLabels2 = New With {Key .EqualString = "equals",
                                     Key .GreaterString = "greater than",
                                     Key .LessString = "less than"}
    

См. также