2016-04-22 7 views
1

Aus meiner Forschung habe ich keine Beweise gefunden, dass dies möglich ist, also fragte ich mich, ob es eine Möglichkeit gibt, diese oder die nächste sauberste Lösung zu machen?Geben Sie einen Parameter für Func zur Deklarationszeit und einen anderen zur Aufruf-/Ausführungszeit an.

Ich möchte vermeiden, ein anderes Argument zu meiner generischen Funktion übergeben, um es sauber zu halten und Modularität zu verbessern.

Betrachten Sie die folgende allgemeine Looping-Funktion, die ein Prädikat Funktion ruft eine bestimmte Bedingung zu überprüfen, während eine Sammlung Looping:

Private Sub LoopAndApplyCondition(Of T)(ByVal collection As IDataCollection, ByVal condition As Func(Of T, String, Boolean), ByRef result As List(Of T)) 
    If Not collection.ActiveItems Is Nothing And collection.Count > 0 Then 
    For Each record In collection 
    '*** 
    '*** I would like to pass in the record into the predicate function here *** 
    '*** 
     Dim meetsCondition As Boolean = condition.Invoke(CType(record, T)) 
     If meetsCondition Then result.Add(CType(record, T)) 
    Next 
    End If 
End Sub 

Dies ist, was die Prädikatfunktion (Bedingung) definiert und nennt diese allgemeine Looping-Funktion, es hat das attributeName-Feld, das ich in die Prädikatfunktion übergeben möchte.

Public Function AllEditableRecords(Of T)(ByVal collection As IDataObjectCollection, ByVal attributeName As String) As List(Of T) 
    Dim result As New List(Of T) 
    '*** 
    '*** I would like to pass in the attributeName field to the predicate function here *** 
    '*** 
    Dim condition As Func(Of T, String, Boolean) = AddressOf CheckIfRecordIsEditable 
    LoopAndApplyCondition(Of T)(collection, condition, result) 
    Return result 
End Function 

Dies ist die Signatur der Prädikatfunktion:

Private Function CheckIfRecordIsEditable(Of T)(record As T, attributeName As String) As Boolean 
    'Returns conditionResult 
End Function 

Um es zusammenzufassen, ich möchte in der String-Parameter zu CheckIfRecordIsEditable über die AllEditableRecords Funktion und die allgemeine passieren Aufzeichnung Parameter über die LoopAndApplyCondition.

Ich glaube nicht, dass es möglich ist, aber bitte beweisen Sie mir falsch. Ich bin glücklich, auch eine Antwort in C# zu akzeptieren, aber VB.NET bevorzugt.

Antwort

0

Nein, es ist nicht möglich, Parameter für Delegaten zu definieren, während sie deklariert werden.

jedoch, was möglich ist, ist die Func und seine Parameter in einer eigenen Klasse zu kapseln:

Public Class RecordCondition(Of T) 
    Public Property CheckConditionHandler As Func(Of T, String, Boolean) 
    Public Property AttributeName As String 
End Class 

Erstellen Sie die RecordCondition in AllEditableRecords:

Public Function AllEditableRecords(Of T)(ByVal collection As IDataObjectCollection, ByVal attributeName As String) As List(Of T) 
    Dim result As New List(Of T) 

    Dim recordCondition As New RecordCondition(Of T) With {.CheckConditionHandler = AddressOf CheckIfRecordIsEditable, .AttributeName=attributeName} 
    LoopAndApplyCondition(Of T)(collection, recordCondition, result) 
    Return result 
End Function 

Anruf CheckConditionHandler in LoopAndApplyCondition :

Private Sub LoopAndApplyCondition(Of T)(ByVal collection As IDataCollection, ByVal condition As RecordCondition(Of T), ByRef result As List(Of T)) 
    If Not collection.ActiveItems Is Nothing And collection.Count > 0 Then 
     For Each record In collection 
      Dim meetsCondition As Boolean = condition.CheckConditionHandler(record, condition.AttributeName) 
      If meetsCondition Then result.Add(CType(record, T)) 
     Next 
    End If 
End Sub 

CheckIfRecordIsEditable ändert sich nicht.

+0

Ja, ich stimme zu, das ist wahrscheinlich die nächste beste Sache, um die Kapselung zu erhalten, danke! – MikeDub

Verwandte Themen