#vb.net #lambda #parameters #delegates
Вопрос:
Часть моей программы состоит из серии шагов, которые либо завершаются, либо истекают через определенный промежуток времени. Условия испытаний сильно различаются. Как мне написать одну функцию, чтобы инкапсулировать все возможности?
Для этого мне в идеале нужно было бы передать необходимое условие функции, которая должна быть оценена внутри функции, а не оцениваться как параметр, а затем передаваться функции.
Это то, что я бы в идеале хотел (значительно упрощено):
Private Function TestCondition(lt;CONDITIONgt;) as Boolean ' Returns True if lt;CONDITIONgt; fulfilled within 10 seconds Dim sw as New Diagnostics.StopWatch sw.Start() While sw.ElapsedMilliseconds lt; 10000 If lt;CONDITIONgt; Return True System.Threading.Thread.Sleep(500) End While sw.Stop() Return False End Function
Функция должна работать с любым выражением, возвращающим логическое значение:
TestCondition(x=5) TestCondition(System.IO.File.Exists("myfile")
Очевидно, что вышесказанное не работает, так как в функцию передаются результаты заданных условий, а не сами условия.
Основываясь на других данных, я, вероятно, смогу сделать это,:
- Реструктуризация моего кода
- Использование делегатов
- Использование лямбда-выражений
но я все еще не вижу, как именно.
Большое спасибо за вашу помощь!
Ответ №1:
Вы можете передать лямбду в функцию, которую можно постоянно пересматривать.
Private Function TestCondition(predicate As Func(Of Boolean)) As Boolean Dim sw As New Diagnostics.Stopwatch() sw.Start() While sw.ElapsedMilliseconds lt; 10000 If predicate() Then Return True System.Threading.Thread.Sleep(500) End While sw.Stop() Return False End Function
Dim result = TestCondition(Function() File.Exists("myfile"))
Комментарии:
1. Спасибо, это именно то, что я искал!!! Поиск лямбда — функций и ключевого слова «Func» привел меня в настоящую кроличью нору. Я многому научился. Еще раз спасибо!!
Ответ №2:
В основном то же самое, что сказал djv,
''' lt;summarygt; ''' waits for a condition for a number of seconds ''' lt;/summarygt; ''' lt;param name="PredicateFunc"gt;Function() conditional check )lt;/paramgt; ''' lt;param name="WaitForTMInSecs"gt;seconds to waitlt;/paramgt; ''' lt;returnsgt;booleanlt;/returnsgt; ''' lt;remarksgt;lt;/remarksgt; Private Function TestCondition(PredicateFunc As Func(Of Boolean), Optional WaitForTMInSecs As Integer = 10) As Boolean Dim sw As Diagnostics.Stopwatch = Diagnostics.Stopwatch.StartNew Dim _wait As TimeSpan = TimeSpan.FromSeconds(WaitForTMInSecs) Dim rv As Boolean = PredicateFunc() Do While Not rv AndAlso sw.Elapsed lt;= _wait System.Threading.Thread.Sleep(500) rv = PredicateFunc() Loop Return rv End Function
Тесты,
Dim result As Boolean result = TestCondition(Function() String.Equals("foo", "bar"), 2) result = TestCondition(Function() String.Equals("foo", "foo"), 2) result = TestCondition(Function() IO.File.Exists("myfile"), 2)
Комментарии:
1. Элегантно — спасибо!