views:

469

answers:

2

I am trying to figure out how to get at an anonymous typed object's properties, when that anonymous type isn't created in the current function.

Specifically, I am binding an ASP.NET ListView to LINQ resultset, then trying to process each item in the ItemDataBound event.

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

What do I need to do in lvGroups_ItemDataBound() to get at the item.DataItem.GroupId?

+1  A: 

Unfortunately there is almost nothing you can do here. The usefulness of anonymous types is limited to the function in which they are created. Once you pass them out of the function you lose all of the strongly typed goodness of there properties. The best solution here is to create a very small struct which encapsulates these properties and uses that instead.

Other options include

  • Use latebinding. This is VB after all
  • Use an unsafe casting type inference trick to make it strongly typed again.

I only mentioned the casting trick because it's a valid solution. However it's even less safe that late binding and given a choice between the two I would choose late binding.

JaredPar
I'd up-vote except for everything after the 1st para.
No Refunds No Returns
@NoRefunds, why? Everything I listed is a valid solution which will unblock the user and solve the problem
JaredPar
+2  A: 

Hey,

When you do the select, either create a class to select as (select new MyClass With { prop assignments here }) so that MyClass is an actual physical class that you can return. Or, you can use the DataBinder class as in:

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

I believe I used that to get a value, which uses reflection to inspect the underlying type.

Brian
That worked. You GetPropertyValue returns a string, and I know I put an Integer in there, so here's my new code:
slolife
Dim currentGroupId As Integer = Integer.Parse(DataBinder.GetPropertyValue(item.DataItem, "GroupId", Nothing))
slolife