Go Back  Xtreme Visual Basic Talk > Visual Basic .NET (2002/2003/2005/2008, including Express editions) > .NET General > convert one generic collection to another


Reply
 
Thread Tools Display Modes
  #1  
Old 01-23-2010, 06:00 AM
piggybank1974's Avatar
piggybank1974 piggybank1974 is offline
Ultimate Contributor
 
Join Date: Mar 2002
Location: weston-super-mare(UK)
Posts: 1,789
Question convert one generic collection to another


Hi There,

I've stumped myself, mental block today it must be!

I have the below code and it works fine, it's this way because I need to manually calculate some data before adding it to the Listview control.

Code:
Dim mList As List(Of ListViewItem) = mDataBase.GetRecords(LvwChecks, "CheckGroups", <Query>, GetType(CheckItem)) If mList.Count > 0 Then Me.LvwChecks.AddRange(mList.ToArray()) End If

What I want to do is basically this List(Of ListViewItem) to List(Of CheckItem)

Like this but it does not work!
Code:
Dim mList As List(Of CheckItem) = CType(mDataBase.GetRecords(LvwChecks, "CheckGroups", <Query>, GetType(CheckItem)), List(Of CheckItem))

this is so I can edit whatever i want, instead of maually having to type cast it e.g

Code:
Dim mCheckItem as CheckItem = CType(mList(<Index>), CheckItem)

Last edited by piggybank1974; 01-23-2010 at 11:23 AM.
Reply With Quote
  #2  
Old 01-23-2010, 06:50 AM
hawkvalley1's Avatar
hawkvalley1 hawkvalley1 is offline
Centurion
 
Join Date: May 2008
Location: Denver, CO USA
Posts: 190
Default

My guess is it has something to do with the return value from the GetRecords function. Without seeing more code this is just a stab in the dark.
Reply With Quote
  #3  
Old 01-23-2010, 10:19 AM
piggybank1974's Avatar
piggybank1974 piggybank1974 is offline
Ultimate Contributor
 
Join Date: Mar 2002
Location: weston-super-mare(UK)
Posts: 1,789
Default

Yeah your correct it returns a List(Of Listviewitem) but I want to cast that to a inherited type List(Of CheckItem) (CheckItem inherits from ListviewItem)
Reply With Quote
  #4  
Old 01-23-2010, 10:36 AM
AtmaWeapon's Avatar
AtmaWeapon AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,419
Default

You can't, unfortunately, but .NET 4 might change that.

There's two fancy words related to this: "contravariance" and "covariance". I can never remember which is which, but one describes this situation. Let's call the correct word "foo". In a language that supports foo, you can cast from one generic type to another if casting of its type parameters would work. I'm assuming that CheckItem is some custom ListViewItem-derived type. If this is so, then if VB .NET supported foo then you could do it. Unfortunately it doesn't. I know that C# 4 is getting some limited contravariance and covariance features, but I'm unclear as to whether VB .NET will get any of them as well.

So what you'll be stuck with is a conversion function:
Code:
Function Convert(ByVal items As List(Of ListViewItem)) As List(Of CheckItem)
    Dim newList As New List(Of CheckItem)()
    For Each item As ListViewItem in items
        newList.Add(CType(item, CheckItem))
    Next
    Return newList
End Function
If that cast would fail anyway I'm not sure why there'd be an expectation that the list types are compatible; this is why I'm assuming the cast is valid.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #5  
Old 01-23-2010, 10:58 AM
piggybank1974's Avatar
piggybank1974 piggybank1974 is offline
Ultimate Contributor
 
Join Date: Mar 2002
Location: weston-super-mare(UK)
Posts: 1,789
Thumbs up

Cheers AW,

All I can say is 'Foo' with several letters added to it that I cannot post As I said it's not to much of a problem I just thought it would make it neater!

Quote:
I'm assuming that CheckItem is some custom ListViewItem-derived type
Yeah your correct as usual my database class has a few clever methods of which GetRecords it just one of them it bascially fills a listviewitem and public properties (I add these to an inherited ListviewItem) in one go.

It's so much easier working with property names than indexes as errors can ocrrure.

the trouble with this one is I needed to add some time calculations on a certain field (Subitem), that is not connected to the database record, I though If I could convert it easily I could swaping in what I want(<Object>.Items.SubItems(<Index>).Text = <Text>) and then add it as a range as normal.

Thanks anyways!
Reply With Quote
  #6  
Old 01-23-2010, 11:19 AM
snarfblam's Avatar
snarfblam snarfblam is offline
Senior Contributor

Forum Leader
* Expert *
 
Join Date: Apr 2005
Location: USA
Posts: 871
Default

You could very easily create a wrapper which performs the cast. You could even create a generic wrapper so that you will always be able to "convert" on list type to another. But you will always run the risk of a runtime exception if items in the original list are not convertible to the type of the "converted" list.

Code:
''' <summary>
''' Wraps a IList(Of T) as a list of a derived type
''' </summary>
Public Class ListWrapper(Of TSource, TNewType As TSource)
    Implements IList(Of TNewType)

    Public Sub New(ByVal source As IList(Of TSource))
        Me.sourceList = source
    End Sub
    Dim sourceList As IList(Of TSource)

    Public Sub Add(ByVal item As TNewType) Implements IList(Of TNewType).Add
        sourceList.Add(DirectCast(item, TSource))
    End Sub

    Public Property Items(index as Integer) As TNewType
        Get
            Return sourceList(index)
        End Get
        Set(ByVal value As TNewType)
            sourceList(index) = DirectCast(value, TNewType)
        End Set
    End Property

    'ect...
End Class
Now we can type Dim myList As IList(Of CheckItem) = New ListWrapper(Of ListViewItem, CheckItem)(someListView.Items). You can continue to reuse this collection as a stand-in for the original.

Also, piggy, you need to break up those long lines. They are messing up the forum, never mind making the code unreadable.
Reply With Quote
  #7  
Old 01-23-2010, 11:30 AM
piggybank1974's Avatar
piggybank1974 piggybank1974 is offline
Ultimate Contributor
 
Join Date: Mar 2002
Location: weston-super-mare(UK)
Posts: 1,789
Default

Hi marble_eater,

Yeah I've changed it in the forum(<Query>) should of done it sooner sorry ADMIN.

I'm not saying I could not create a wrapper, but for one it's pointless the extra code is overkill I think! It only displays a max of 14 items depending on what Welfare checks have to be made, and is only used on this form alone.

I dont want to burst you bubble and nice idea and thanks again.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
 
 
-->