0

I have a custom class that inherits from List(of T). How can I find an object from the List with a custom property?

Sample code:

Public class baseClass
    Property ID
End class

Public class Member
   Inherits BaseClass

   Property UserID As Integer
End Class

Public Class LCMSCollection(Of T As BaseClass)
    Inherits System.Collections.Generic.List(Of T)


End Class

What I want to be able to do is find a member by UserId. I would prefer something like this:

Dim userId = 3
Dim members = MemberService.GetMembers(<some parameter>)
Dim member = members.<some method name>(userId)

In other circumstances it would be:

Dim playerid = 6
Dim team = TeamService.GetTeam(<some parameter>)
Dim player  = teams.<some method name>(playerid)

I'm thinking about a delegate and changing the Property to a function, but I don't know how to proceed.

Currently I have this:

Dim playerid = 6
Dim team = TeamService.GetTeam(<some parameter>)
Dim player = TeamService.GetPlayer(team, playerid)

This is not satisfying for several reasons. First of all getting an item from a collection should be done on the collection like getting an item from a list. Futhermore in the current situation one needs to add custom methods for each an every instance type of the collection. To avoid that one could create a general method getItem in a base class ad have all repositories like in this example Teams and Members inherit from this base class. BUt this cannot account for the fact that every instance class of baseclass has a different property or method to use as a filter. Doing it like this seems to me to introduce interdependencies and complexity which I was trying to avoid by using a generic collection.

Any suggestions? Am I trying to solve a non issue or approaching this from the wrong angle.

Btw I use both C# and VBnet so answers in either one language is OK

Sigur
  • 216
  • 3
  • 11
  • 2
    var item = members.FirstOrDefault(m => m.UserID == id); – itsme86 Jul 11 '14 at 15:18
  • Which version of the Framework? If you are using 3.5 or newer, is there some reason why LINQ is insufficient for you? – Steven Doggart Jul 11 '14 at 15:18
  • 2
    You shouldn't be inheriting from `List` here. You should be composing it. – Servy Jul 11 '14 at 15:20
  • @Steven: LINQ isn't really used in the solution I'm working on so I forgot about that. I'll look into that. Thanks for reminding me. – Sigur Jul 11 '14 at 15:22
  • @Servy: I had been thinking about that, but then I would miss out on all the method available from List. So I decided against that. Any reason why composing is better than inheriting in this case? – Sigur Jul 11 '14 at 15:25
  • @Sigur Your object is conceptually not a list. It represents an object that has a list, even though it isn't one. You can still perform list operations on that composed list, which is what you should be doing, not performing them on the object itself. – Servy Jul 11 '14 at 15:28
  • @Servy: I try to understand why my object isn't a list, but I don't. What I need is a collection of instances of baseClass. That seems to me to be a list. I have changed my code a bit to better show what I'm doing. Please clarify more why object is a list itself but an object with a list. – Sigur Jul 14 '14 at 12:52
  • @Sigur http://stackoverflow.com/a/21694054/1159478 – Servy Jul 14 '14 at 14:04
  • @Servy: I had read that post, but not closely enough to fully understand it. I have read it again more closely and better understand what your saying. Recently it appeared to me that objects provided by the framework are to use and not to be. Which follows the same line of thought as the distinction between functionality (i.e. mechanisms) and business objects. Thanks helping clear my thoughts. – Sigur Jul 16 '14 at 11:41

2 Answers2

0

Use LINQ.

Dim teams As List(Of Team) = [your team list]
Dim id As Integer = 10
Dim match As Team = (From item As Team In teams Select item Where item.ID = id).FirstOrDefault()
Bjørn-Roger Kringsjå
  • 9,582
  • 6
  • 32
  • 59
0

So the idea is that you want to 'filter' your list by some condition? Try this (C#):

Player match = PlayerList.Find(p => (p.ID == 5));

Will scan your collection and return the first match. Alternatively, if you want all matches, you can use FindAll, which returns an IEnumerable.

Timon Knigge
  • 287
  • 2
  • 12