Как отлаживать предикаты в C # / Visual Studio? - PullRequest
9 голосов
/ 09 июня 2011

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

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

Ответы [ 3 ]

5 голосов
/ 09 июня 2011

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

2 голосов
/ 09 июня 2011

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

Либо используйте Expression, как подсказывает @BenVoigt, либо не используйте анонимные лямбды для своих предикатов: (VB.NET answer: Используйте названный вами 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
0 голосов
/ 09 июня 2011

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

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

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

...