【问题标题】:Specify one parameter for Func at declaration time and another at invoke/execution time在声明时为 Func 指定一个参数,在调用/执行时指定另一个参数
【发布时间】:2016-04-22 05:02:52
【问题描述】:

根据我的研究,我没有发现任何证据表明这是可能的,所以我想知道是否有办法做到这一点或下一个最干净的解决方案?

我想避免将另一个参数传递给我的泛型函数以保持它的整洁并提高模块化。

考虑以下通用循环函数,它在循环集合时调用谓词函数来检查某个条件:

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

这是定义谓词函数(条件)并调用此通用循环函数的内容,它具有我想传递给谓词函数的属性名称字段。

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

这是谓词函数的签名:

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

总而言之,我想通过 AllEditableRecords 函数将字符串参数传递给 CheckIfRecordIsEditable,并通过LoopAndApplyCondition

我不认为这是可能的,但请证明我错了。 我也很乐意接受 C# 中的答案,但首选 VB.NET。

【问题讨论】:

    标签: .net vb.net generics delegates func


    【解决方案1】:

    不,在声明委托时不能为委托定义参数。

    但是,可以将 Func 及其参数封装在它自己的类中:

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

    AllEditableRecords中创建RecordCondition

    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
    

    LoopAndApplyCondition中调用CheckConditionHandler

    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 不会改变。

    【讨论】:

    • 是的,我同意,这可能是保持封装的下一个最佳方法,谢谢!
    猜你喜欢
    • 2016-01-03
    • 2012-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-04
    • 1970-01-01
    • 2014-07-27
    相关资源
    最近更新 更多