2009-10-07 3 views
1

Я часто вызываю функции из lambdas, поскольку предоставленный делегат не соответствует или не имеет достаточных параметров. Это раздражает, что я не могу делать лямбда на подпрограммах. Каждый раз, когда я хочу это сделать, я должен обернуть свою подпрограмму в функцию, которая ничего не возвращает. Не очень, но это работает.Вызов подпрограмм из лямбда в vb.net

Есть ли другой способ сделать это, что делает эту гладкость/красивее?

Я читал, что вся эта неадекватность лямбда, вероятно, будет исправлена ​​в VS2010/VB10, поэтому мой вопрос больше из любопытства.

Простой пример:

Public Class ProcessingClass 
    Public Delegate Sub ProcessData(ByVal index As Integer) 
    Public Function ProcessList(ByVal processData As ProcessData) 
     ' for each in some list processData(index) or whatever' 
    End Function 
End Class 

Public Class Main 

    Private Sub ProcessingSub(ByVal index As Integer, _ 
           ByRef result As Integer) 
     ' (...) My custom processing ' 
    End Sub 

    Private Function ProcessingFunction(ByVal index As Integer, _ 
             ByRef result As Integer) As Object 
     ProcessingSub(index, result) 
     Return Nothing 
    End Function 

    Public Sub Main() 
     Dim processingClass As New ProcessingClass 
     Dim result As Integer 
     ' The following throws a compiler error as ' 
     ' ProcessingSub does not produce a value' 
     processingClass.ProcessList(_ 
      Function(index As Integer) ProcessingSub(index, result)) 
     ' The following is the workaround that' 
     ' I find myself using too frequently.' 
     processingClass.ProcessList(_ 
      Function(index As Integer) ProcessingFunction(index, result)) 
    End Sub 

End Class 

ответ

1

Если вы обнаружите, что делаете это слишком часто и, как правило, с одним и тем же типом данных, вы можете обернуть делегат в класс.

Создать базовый класс, который преобразует делегата:

Public MustInherit Class ProcessDataBase 
    Public Shared Widening Operator CType(operand As ProcessDataBase) as ProcessingClass.ProcessData 
     Return AddressOf operand.Process 
    End Sub 

    Protected MustOverride Sub Process(index As Integer) 
End Class 

наследуются от класса:

Public Class ProcessResult 
    Inherits ProcessDataBase 

    Public Result As Integer 

    Protected Overrides Sub Process(index as Integer) 
     ' Your processing, result is modified. 
    End SUb 
End Class 

Использование:

Public Class Main() 
    Public Sub Main() 
     Dim processingClass As New ProcessingClass 
     Dim processor As New ProcessResult 

     processingClass.ProcessList(processor) 
     Dim result as integer=processor.Result 
    End Sub 
End Class 
+0

Видя ваше решение, я понимаю, что на самом деле я поддерживаю состояние, которое, конечно, должно делать с классом. И с вашим решением аргументы делегату уже не важны, что делает его еще красивее. – Tewr

0

Это фиксируется в VB10, то VS10 Бета available, если это вариант для вас, чтобы использовать его. В VB10 у вас есть lambdas без возвращаемого значения, а также встроенные subs/functions.

На данный момент, может быть, вы могли бы просто забыть лямбды и работать с делегатами? Что-то вроде:

processingClass.ProcessList(AddressOf ProcessingSub) 
+0

хорошо, как указано в вопросе выпуска когда спецификация делегата не соответствует реализации. Вызов 'processClass.ProcessList (AddressOf ProcessingSub)' даст ошибку времени компиляции как 'ProcessingSub (индекс ByVal As Integer, результат ByRef As Integer)' не соответствует делегату 'ProcessData (индекс ByVal As Integer)' – Tewr

+0

Can not вы просто добавляете результат byref к параметрам ProcessData и отправляете результат в функцию ProcessList? –

+0

Ну, дело в том, что ProcessClass не должен знать, как я реализую ProcessData. В противном случае все дело в том, что делегат будет потерян. Наверное, я упростил свой пример. Реалистичный делегат ProcessData должен принять какую-то структуру данных в качестве аргумента. И в разных ситуациях у меня разные реализации ProcessData с разными аргументами, в то время как processClass остается счастливо не знакомым с тем, что происходит внутри ... – Tewr

Смежные вопросы