views:

95

answers:

3

I have the following code:

Public Shared Function GetAvailableManufacturers() As List(Of Manufacturer)
    'first get all the live orders and extract their mfrs'
    Dim sos As List(Of OrderForm) = GetFormsByStatus(StockStatus.Building)
    Dim unavailableMfrs As New List(Of Manufacturer)
    For Each so As StockingOrder In sos
        unavailableMfrs.Add(so.Source)
    Next

    'then remove all mfrs with an open SO from a list of all mfrs'
    Dim allMfrs As List(Of Manufacturer) = Manufacturer.GetManufacturers
    Return allMfrs.Except(unavailableMfrs) <----- error here
End Function

Explanation of what the above does:

  • GetFormsByStatus() self-explanatory
  • GetManufacturers() returns a list of all manufacturers in the database

My idea to get available manufacturers was to get a list of all the manufacturers in my open forms, then get a list of all manufacturers and exclude all the manufacturers in the first list, illustrated like so (pseudo):

List A: {1,2,3,4,5,6,7,8,9,10}
List B: {5,7,10}
Result: {1,2,3,4,6,8,9}

I have set up my Manufacturer class according to this article so that it can be compared, but I'm still getting this error:

Unable to cast object of type '<ExceptIterator>d__92'1[csCore.Manufacturer]' to type 'System.Collections.Generic.List'1[csCore.Manufacturer]'.

I thought at first that because during testing GetFormsByStatus() returns 0 results maybe that was causing problems, but it doesn't make sense that Except() wouldn't work if the provided list had 0 items. Can anyone spot what I'm doing wrong?

Thanks so much!

+6  A: 

The function expects a List(Of Manufacturer) return type, not an IEnumerable(Of Manufacturer), so adding a .ToList() to the return value should fix it:

Return allMfrs.Except(unavailableMfrs).ToList()
Mauricio Scheffer
oy. the devil is always in the details. thanks for taking the time to sort through my question and figure out the simple answer :)
Jason
True, but I really think the opposite approach is better: Make the method return an `IEnumerable(of Manufacturer)` instead, let the caller decide whether or not to spend the extra resources materializing it into a list. In fact, very rarely should *any* method actually return a mutable collection.
Aaronaught
@aaronaught - truth. this answer is still the correct answer for the question, but you are absolutely right. my actual implementation reflects this.
Jason
+1  A: 

Your function is declared as returning List(Of Manufacturer), but your Return statement is returning only an IEnumerable(Of Manufacturer). Change the return statement to:

Return allMfrs.Except(unavailableMfrs).ToList()

If you turn Option Strict On, I believe VB will catch this kind of error at compile time, instead of blowing up at runtime.

itowlson
+1  A: 

The problem is that Enumerable.Except returns IEnumerable<T>, but your return type is List(Of T).

Change your last line to:

Return allMfrs.Except(unavailableMfrs).ToList()
Reed Copsey