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

В режиме отладки, если я наведу указатель мыши на предикат, я вижу только имена типов и непонятные символы. Это очень затрудняет отладку кода, например, чтобы узнать, что предикат содержит некоторая переменная. Я обычно присваиваю значения предикатов, используя лямбда-выражения. Есть ли способ получить представление о том, что содержат предикаты?

Например, если у меня есть Predicate<object> myPred переменная или List<Predicate<object>> predList переменные, как я могу отладить, какое значение имеет myPred или что predList содержит во время выполнения?

3 ответа

Решение

[Я не проверял опыт C# IDE, но на самом деле опыт VS2010 VB.NET.]

Либо использовать Expression как предлагает @BenVoigt, или не используйте анонимные лямбды для своих предикатов: (VB.NET answer: Use Functions названный вами и укажите их с AddressOf оператор).

Ответ C# - это что-то вроде: объявить явные функции, названные вами, и указать имя функции при назначении предиката.

Вот мой тестовый код VB.NET, который подтверждает, что хотя бы один способ динамического создания предикатов может быть успешно назван. В IDE VB.NET их легко увидеть по имени.

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" & 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

Вы, вероятно, хотите Expression<Predicate<T>>, Это может быть преобразовано в Predicate<T> для того, чтобы вызвать его, но сохраняет информацию о лямбда-структуре.

Если ты имеешь ввиду что в таком примере

new List<int>()
.Select(i => i + 1);

вы хотели бы отладить часть i + 1, затем вы можете поместить курсор мыши (курсор) где-то в i + 1 и нажать F9, чтобы добавить точку останова в это выражение

Другие вопросы по тегам