2010-02-12 79 views
2

我想弄清楚如何获得匿名类型的对象的属性,当时没有在当前函数中创建匿名类型。如何从VB.NET中的匿名类型获取属性

具体来说,我将ASP.NET ListView绑定到LINQ结果集,然后尝试处理ItemDataBound事件中的每个项目。

Option Explicit On 
Option Strict On 

Class MyPageClass 

    Private Sub Bind() 
     Dim items As ItemData = FetchItemData() 

     Dim groups = From s In items Group s By Key = s.GroupId Into Group _ 
       Select GroupID = Key, GroupData = Group 

     ' This works fine: 
     Dim groupId As Integer = groups(0).GroupID 

     lvGroups.DataSource = groups 
     lvGroups.DataBind() 
    End Sub 

    Private Sub lvGroups_ItemDataBound(ByVal sender As Object, ByVal e As ListViewItemEventArgs) Handles lvGroups.ItemDataBound 
     If e.Item.ItemType = ListViewItemType.DataItem Then 
      Dim item As ListViewDataItem = DirectCast(e.Item, ListViewDataItem) 
      Dim groupData = item.DataItem ' This is the anonymous type {GroupId, GroupData} 

      ' Next Line Doesn't Work 
      ' Error: Option Strict disallows late binding 
      Dim groupId As Integer = groupData.GroupId 

     End If 
    End Sub 

End Class 

我需要什么,在lvGroups_ItemDataBound做()来获得在item.DataItem.GroupId?

回答

4

当你做选择时,要么创建一个类来选择(选择新的MyClass With {prop assignments here}),这样MyClass就是你可以返回的实际物理类。或者,你可以使用DataBinder的类,如:

DataBinder.GetPropertyValue(item.DataItem, "GroupId", null); 

我相信我用得到的值,它使用反射来检查的基础类型。

+0

工作正常。你GetPropertyValue返回一个字符串,我知道我把一个整数在那里,所以这里是我的新代码: – slolife 2010-02-12 19:27:19

+0

Dim currentGroupId As Integer = Integer.Parse(DataBinder.GetPropertyValue(item.DataItem,“GroupId”,Nothing)) – slolife 2010-02-12 19:29:17

1

不幸的是,这里几乎没有什么可以做的。匿名类型的用处仅限于创建它们的函数。一旦你将它们从函数中传递出去,就会失去所有属性的强类型优点。这里最好的解决方案是创建一个封装这些属性的非常小的结构,并使用它。

其他选项包括

  • 使用latebinding。这是VB毕竟
  • 使用不安全的转换类型推断技巧,使其再次强烈键入。

我只提到了铸造技巧,因为这是一个有效的解决方案。然而,后期绑定和两者之间的选择我选择后期绑定更不安全。

+2

除了第一段之后的所有内容外, – 2010-02-12 19:11:41

+0

@NoRefunds,为什么?我列出的所有内容都是一个有效的解决方案,可以解除用户的阻碍并解决问题 – JaredPar 2010-02-12 19:27:30

1

下面是一个从Linq获取匿名类型项目到xml然后通过电子邮件发送其属性的例子。 linq项目作为匿名类型传递给sendmail函数,并通过反射投资其属性:

Public Function ProcessFile(ByRef i_fullFilename As String) As String 

    Dim result As String = String.Empty 

    Try 

     Dim xDoc As XDocument = XDocument.Load(i_fullFilename) 

     Dim message = From q In xDoc.Descendants _ 
         Where q.Name.LocalName = "ContinuousMessage" _ 
         Select q 

     Dim nsName As String = message.FirstOrDefault.Name.NamespaceName 

     Dim ns As XNamespace = nsName 

     Dim messageCollection = From msg In xDoc.Descendants(ns + "ContinuousMessage") _ 
           Select customOfficeNumber = msg.Element(ns + "customOfficeNumber").Value, _ 
           unitCode = msg.Element(ns + "unitCode").Value, _ 
           leadingFileNumber = msg.Element(ns + "leadingFileNumber").Value, _ 
           messageType = msg.Element(ns + "messageType").Value, _ 
           note = msg.Element(ns + "note").Value, _ 
           sendingOrPrintingDate = CType(msg.Element(ns + "sendingOrPrintingDate").Value, Date) 

     Dim commonNsName As String = "http://com.com/some/common.xsd" 
     Dim commonNs As XNamespace = commonNsName 

     Dim tgpiCollection = From item In xDoc.Descendants(ns + "TPGIdentifier") _ 
          Select fileNumber = item.Element(commonNs + "fileNumber").Value, _ 
          numeral = item.Element(commonNs + "numeral").Value, _ 
          fillingNumber = item.Element(commonNs + "FillingNumber").Value 

     For Each item In messageCollection 
      SendMail(item, "Info") 
     Next 

    Catch ex As Exception 
     result &= ex.Message 
    End Try 

    Return result 

End Function 


Private Sub SendMail(ByRef i_item, ByVal i_errorDescriptionString) 

    Dim email As New MailMessage 
    email.From = New MailAddress("[email protected]") 
    email.To.Add(New MailAddress("[email protected]")) 
    email.Subject = "New message from customs received 5115" 

    Dim name As String = String.Empty 
    Dim value As String = String.Empty 
    Dim body As String = String.Empty 
    Dim nextLine As String = String.Empty 

    Dim propertiesInfo As PropertyInfo() = i_item.GetType().GetProperties() 
    For Each prop As PropertyInfo In propertiesInfo 

     name = prop.Name 
     value = prop.GetValue(i_item, Nothing) 
     nextLine = String.Format(" {0}: {1} {2}", name, value, vbCrLf) 
     body = body & nextLine 

    Next 

    If Not String.IsNullOrEmpty(i_errorDescriptionString) Then 
     nextLine = String.Format(" Error Description: {1} {2}", name, i_errorDescriptionString, vbCrLf) 
     body = body & nextLine 
    End If 

    email.Body = body 


    Dim smtp As New SmtpClient() 
    smtp.Host = "smtp.local" 
    smtp.Send(email) 

End Sub 
相关问题