#c# #visual-studio #debugging #lambda #predicates
#c# #visual-studio #отладка #лямбда #предикаты
Вопрос:
В режиме отладки, если я наведу указатель мыши на предикат, я увижу только некоторые имена типов и некоторые непонятные символы. Это очень затрудняет отладку кода, например, чтобы узнать, какой предикат содержит некоторая переменная. Обычно я присваиваю этим предикатам значения, используя лямбда-выражение. Есть ли какой-нибудь способ получить некоторое представление о том, что содержат предикаты?
Например, если у меня есть Predicate<object> myPred
переменная или List<Predicate<object>> predList
переменные, как я могу отладить, какое значение имеет myPred или что содержит predList во время выполнения?
Комментарии:
1. В качестве альтернативы вы могли бы написать модульные тесты для проверки поведения кода.
2. Учитывая вашу дополнительную информацию в вашем комментарии к моему ответу, я полагаю, вам нужно расширить этот вопрос или задать новый вопрос о способах генерации «отладочных» лямбда-выражений. ИМХО, ответ на этот вопрос заключается в генерации именованных функций, которые в VB.NET доступны для чтения и отладки.
Ответ №1:
Вы, вероятно, хотите Expression<Predicate<T>>
. Для его вызова его можно преобразовать в Predicate<T>
, но при этом сохраняется информация о лямбда-структуре.
Комментарии:
1. как я могу использовать это с лямбда-выражением, и что будет показано при отладке?
2. @Louis: Я добавил пример, дайте мне знать, если у вас возникнут дополнительные вопросы.
3. И именно поэтому вы не должны помещать код за пределы вашего ответа — ссылка не работает …
4. Код — это не мой ответ, это просто для получения дополнительной информации. Все важные ключевые слова и подход приведены прямо здесь, на SO.
Ответ №2:
[Я не проверял работу с C # IDE, но на самом деле VS2010 VB.NET опыт.]
Либо используйте Expression
, как предлагает @BenVoigt, либо не используйте анонимные лямбды для своих предикатов: (VB.NET ответ: Используйте Functions
названные вами и укажите их с помощью AddressOf
оператора.)
Ответ C # примерно такой: объявляйте явные функции, названные вами, и указывайте имя функции при назначении предиката.
Вот мой тест VB.NET код, который подтверждает хотя бы один способ динамического создания предикатов, может быть успешно назван. В VB.NET IDE их легко увидеть по названию.
Module Module1
Sub Main()
For i = 1 To 2
'Dim p As Predicate(Of Object) = Function(o) (o Is Nothing)
'Dim p As Predicate(Of Object) = AddressOf NamedPredicate
Dim p As Predicate(Of Object) = GeneratePredicate(i)
Dim q As Expressions.Expression(Of Predicate(Of Object)) = Function(o) (o IsNot Nothing)
If p(q) Then Console.WriteLine((q.Compile)(p))
Next
End Sub
Private Function NamedPredicate(ByVal o As Object) As Boolean
Return (o Is Nothing)
End Function
Private Function GeneratePredicate(ByVal i As Integer) As Predicate(Of Object)
Dim gp = New Reflection.Emit.DynamicMethod("DynPred" amp; i, GetType(Boolean), {GetType(Object)})
Dim mb = gp.GetILGenerator
mb.Emit(Reflection.Emit.OpCodes.Ldarg, 0)
mb.Emit(Reflection.Emit.OpCodes.Ldnull)
mb.Emit(Reflection.Emit.OpCodes.Ceq)
If i = 2 Then
mb.Emit(Reflection.Emit.OpCodes.Ldc_I4_0)
mb.Emit(Reflection.Emit.OpCodes.Ceq)
End If
mb.Emit(Reflection.Emit.OpCodes.Ret)
GeneratePredicate = DirectCast(gp.CreateDelegate(GetType(Predicate(Of Object))), Predicate(Of Object))
End Function
End Module
Комментарии:
1. Моя программа создает множество функций программно, поэтому я не думаю, что это можно сделать
Ответ №3:
если вы имеете в виду, что в таком примере
new List<int>()
.Select(i => i 1);
вы хотели бы отладить часть i 1, затем вы можете поместить курсор мыши (каретку) где-нибудь на i 1 и нажать F9, что добавит точку останова в это выражение
Комментарии:
1. Нет, я не это имел в виду. Я отредактировал свой вопрос, чтобы добавить пояснения