2009-04-01 5 views
0

Ich versuche, eine generische Funktion zu erstellen, die die Schüler in meinem einführenden VB .NET-Kurs verwenden können, um ein einzelnes dimensionales Array einer Struktur zu suchen.Erstellen einer Funktion, die eine generische Struktur verwendet?

Meine Struktur und Anordnung wie folgt aussehen:

Private Structure Survey 
    Dim idInteger As Integer 
    Dim membersInteger As Integer 
    Dim incomeInteger As Integer 
    Dim stateString As String 
    Dim belowPovertyLevelBoolean As Boolean 
End Structure 

Private incomeSurvey(199) As Survey 

Meine generische Funktion Header wie folgt aussieht:

Private Function FindSurveyItem(Of xType As Structure) 
(ByVal surveyIDInInt As Integer, ByVal surveyArrayIn() As xType) As Integer 

?????? 

End Function 

Mein Aufruf der Funktion wie folgt aussieht:

If FindSurveyItem(Of Survey)(CInt(idTextBox.Text), incomeSurvey) <> -1 Then 

Meine Frage is: Gibt es eine Möglichkeit, die einzelnen Strukturfelder im Array von innerhalb der Funktion zu referenzieren? Ich habe versucht, es generisch zu machen, so dass der Schüler sein Array einfach in die Funktion übergeben könnte - seine Struktur könnte anders benannt werden als meine und die Feldnamen könnten anders sein.

Ich vermute, es gibt andere Möglichkeiten, um mit dieser Situation umzugehen, aber ich habe versucht, es zu einem einfachen eindimensionalen Array einer Struktur zu halten. Ich glaube nicht, dass es möglich ist, zu tun, was ich will, aber ich habe mich gefragt, was andere denken.

+1

Bitte erzählen Sie mir nicht Sie Studenten sind lehren die Art als Teil einschließen des Variablennamens! –

+0

Ich wurde angewiesen, Strukturen nur zu verwenden, wenn die Instanzgröße weniger als 16 Bytes betrug. Es scheint, als wären Ihre Instanzgrößen viel größer als 16 Byte. –

+0

Joel, ja, die Studenten sollen den Typ als Suffix des Variablennamens angeben. Das Lehrbuch, das ich benutze, tut dies und vor allem brauchen sie eine Erinnerung an den Typ, den sie benutzen. Ich weiß, dass das aus der Sicht eines Entwicklers stumm klingt, aber das sind Anfänger. –

Antwort

0

Was Sie suchen sind Prädikate, wenn verwenden, netto 3,5

dim arr() as structure 
Array.Find(arr, function(item)(item.MyMember = MemberToMatch)) 

Mehr combersome in früheren Versionen, see here für weitere Informationen

Der Punkt ist, dass Ihre Funktion sehr aussehen würde eine Implementierung von Array.Find (wenn Sie die angegebene Funktion nicht verwenden wollten), und die Schüler müssten ihre eigene Prädikatfunktion schreiben.

+0

Das ist nicht unbedingt eine schlechte Sache: Er erwähnte, dass er eine Klasse unterrichtet. Manchmal implementieren Klassenbeispiele gemeinsame Strukturen neu, um zu zeigen, wie es geht. –

+0

Ich wollte es nicht so klingen, als wäre es eine schlechte Sache, ehrlich! Capterners studieren, wie Bäume wachsen, Bauherren studieren, woraus Concrete gemacht wird, "Funktionsautoren" lernen, wie Funktionen geschrieben werden :) –

+0

Was sind Capenters? Leute, die Zelte machen? ;-) –

0

Nein, gibt es nicht. Sie können den Typ zum Zeitpunkt der Kompilierung nicht kennen, daher können Sie nicht auf Mitglieder dieses Typs zugreifen. Sie müssten von einer Struktur zu einer Klasse wechseln, die IComparable implementieren muss, so dass Sie CompareTo zwischen dem übergebenen Element und dem übergebenen Array verwenden können.

Obwohl es nicht ganz klar ist, was Sie versuchen, innerhalb zu tun Ihre Methode, so rate ich mit dem Namen der Methode.

+0

Garry, danke. Ich wusste, dass der eigentliche Typ zur Kompilierzeit unbekannt war - das war es, was mich vermuten ließ, dass es keine einfache Lösung gab. Ich war nur persönlich neugierig auf einen möglichen Weg, es zu tun. Du hast bestätigt, was ich vermutet habe. –

1

Wenn Sie einen genrischen Typparameter T haben, können Sie nur auf Member von Instanzen von T zugreifen, von denen bekannt ist, dass sie zur Kompilierungszeit existieren. Da jeder Typ von Object abgeleitet ist, stehen Ihnen nur die Member von Object zur Verfügung - ToString(), GetType(), GetHashCode() und Equals().

Wenn Sie auf andere Mitglieder zugreifen wollen, müssen Sie einschränken, was T sein darf. In Ihrer Situation wäre eine Schnittstelle der richtige Weg. Details finden Sie unter MSDN.

Sie könnten auch versuchen, Reflexion zu verwenden oder den tatsächlichen Typ zur Laufzeit zu überprüfen und einen Cast durchzuführen. Die erste ist schwer zu tun, wenn Sie nicht viel über die Arten wissen, die Sie bekommen werden. Und das später erfordert, dass Sie mögliche Typen bei der Kompilierung kennen und auch nicht in Ihrer Situation funktionieren.

Eine andere Möglichkeit besteht darin, einen Delegaten an die Suchmethode zu übergeben, die den tatsächlichen Vergleich durchführt.

0

Sie können Reflektion verwenden, um diese Felder zu erhalten, aber in diesem Fall hätte das keine große Bedeutung. Woher weißt du, dass der übergebene Typ das Feld hat, nach dem du suchst? Es gibt auch andere Probleme mit diesem Code.

Stattdessen würde ich normalerweise eine Schnittstelle für etwas wie diese erstellen, die eine öffentliche ID-Eigenschaft hatte, und meine Eingabe auf die Funktion beschränken, um diese Schnittstelle zu implementieren, oder wie andere erwähnte eine integrierte Funktion in der verwenden clr.

Aber das kann voraus sein, wo Ihre Schüler sind. Wenn Sie nur ein Beispiel für eine generische Funktion wollen, ist mein Vorschlag, ihnen eine typsichere Implementierung der alten vb imediate if Funktion zu zeigen:

Public Function IIf(Of T)(ByVal Expression As Boolean, ByVal TruePart As T, ByVal FalsePart As T) AS T 
    If Expression Then Return TruePart Else Return FalsePart 
End Function 

Beachten Sie, dass diese veraltet ist auch, wie es in VS2008 und darüber hinaus Sie kann stattdessen den neuen Operator If verwenden, der besser mit der Typinferenz arbeitet und nicht versucht, den Ausdruck auszuwerten, der nicht zurückgegeben wird.

2

Gibt es eine Möglichkeit, die einzelnen Strukturfelder im Array innerhalb der Funktion zu referenzieren?

Generisch anstelle eines Arrays benötigen Sie eine Sammlungsart. In LINQ-Code:

Dim Surveys = From svys In xType 
    Where svys.idInteger = surveyIDInInt 
    Select svys 

For Each rSurveys In svys 
    '''' Your Code 
Next 

Dies wird grobe Antwort füllen Sie die Details (ich weiß vorstellen LINQ ohne SQL-DB !!)

Verwandte Themen