Как отлаживать предикаты в C # / Visual Studio?

#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. Нет, я не это имел в виду. Я отредактировал свой вопрос, чтобы добавить пояснения