2010-07-26 4 views
3

J'ai la configuration suivante:Trouver un élément dans une liste (de T) par les valeurs x, y et z

Class A 
     property x as string 
     property y as int 
     property z as String 

End Class 

Class CollOfA 
    inherits List(Of A) 

End Class 

Ce que je voudrais est une propriété d'objet dans la collection que je peux dire:

dim c as new CollOfA 
c.item("this", 2, "that") 

J'ai essayé la mise en œuvre ce qui suit dans CollOfA:

Class CollOfA 
    inherits List(Of A) 

    Default Public Overridable Shadows ReadOnly Property Item(ByVal x As String, ByVal y As Integer, byval z as string) 
     Get 
      ' I want to do something like: 
      ' ForEach item in me see if anything matches these three things 

     End Get 
    End Property 
End Class 

Je sais prédicats, mais je me bats avec la façon de régler la cr iteria du prédicat (c.-à-d. passant x, y et z).

Est-ce que quelqu'un a implémenté quelque chose de similaire?

Répondre

6

Voici deux façons de répondre à votre question. Une façon utilise une syntaxe de requête LINQ pour filtrer; la seconde utilise un objet personnalisé pour contenir vos paramètres de prédicat, puis utilise cet objet pour exécuter le filtre.

En utilisant la syntaxe LINQ dans votre propriété Item:

Default Public Overridable Shadows ReadOnly Property Item(ByVal x As String, ByVal y As Integer, ByVal z As String) As IEnumerable(Of A) 
    Get 
     Return (From theA In Me 
       Where (theA.x = x And theA.y = y And theA.z = z) 
       Select theA) 

    End Get 
End Property 

L'autre façon serait de créer une classe PredicateParameter pour tenir vos paramètres et aussi une méthode déléguée qui est utilisé pour exécuter le filtre. J'ai vu cela sur un commentaire MSDN - voici le link. Voici la classe:

Class PredicateParams 

    Public Sub New(ByVal theA As A) 
     Criteria = theA 
    End Sub 

    Public Property Criteria As A 

    Public Function IsMatch(ByVal theA As A) As Boolean 
     Return (theA.x = Criteria.x And theA.y = Criteria.y And theA.z = Criteria.z) 
    End Function 

End Class 

Et voici la propriété qui se trouve dans la classe CollOfA qui l'utilise:

Public Overridable Shadows ReadOnly Property ItemPred(ByVal x As String, ByVal y As Integer, ByVal z As String) As IEnumerable(Of A) 
    Get 
     Dim predA As New A 
     predA.x = x 
     predA.y = y 
     predA.z = z 

     Dim pred As New PredicateParams(predA) 

     Return Me.FindAll(AddressOf pred.IsMatch) 
    End Get 

End Property 

Enfin, voici un coureur de console pour tester.

Sub Main() 
    Dim mycoll As New CollOfA() 


    For index = 1 To 100 
     Dim anA As New A() 
     anA.x = (index Mod 2).ToString() 
     anA.y = index Mod 4 
     anA.z = (index Mod 3).ToString() 
     mycoll.Add(anA) 
    Next 

    Dim matched As IEnumerable(Of A) = mycoll.Item("1", 3, "2") 
    Dim matched2 As IEnumerable(Of A) = mycoll.ItemPred("1", 3, "2") 

    Console.WriteLine(matched.Count.ToString()) 'output from first search 
    Console.WriteLine(matched2.Count.ToString()) 'output from second search (s/b same) 
    Console.ReadLine() 

End Sub 

Espérons que cela aide. Il y a peut-être une façon plus élégante de le faire, mais je n'en ai pas vu. (BTW, je travaille généralement avec C#, donc mon VB.NET est un peu rouillé.)

1

Si votre classe A est assez simple, vous pourrez peut-être vous en sortir avec un getter de propriété par défaut d'une ligne et le Find méthode de votre liste, quelque chose comme ceci:

Public Class CollOfA 
    Inherits List(Of A) 

    Default Public Overloads ReadOnly Property Item(ByVal x As String, ByVal y As Integer, ByVal z As String) As A 
     Get 
      Return Find(Function(a As A) (((a.x = x) AndAlso (a.y = y)) AndAlso (a.z = z))) 
     End Get 
    End Property 
End Class 

Je l'ai fait dans Visual studio 2008, donc je ne sais pas comment ça va marcher dans d'autres versions.

Questions connexes