Louis Rhys
Louis Rhys

Reputation: 35627

How to debug Predicates in C#/Visual Studio?

In debugging mode, if I hover over a predicate, what I see is just some type names and some non-understandable symbols. This makes it very difficult to debug a code, for example to know what predicate some variable is holding. I usually assign this predicates values using lambda expression. Is there any way to have some idea of what the predicates contain?

For example, if I have a Predicate<object> myPred variable or a List<Predicate<object>> predList variables, how can I debug what value myPred has or what predList contains at runtime?

Upvotes: 10

Views: 2360

Answers (3)

Ben Voigt
Ben Voigt

Reputation: 283694

You probably want Expression<Predicate<T>>. It can be converted to Predicate<T> in order to call it, but retains the information about the lambda structure.

Upvotes: 5

Mark Hurd
Mark Hurd

Reputation: 10931

[I haven't checked the C# IDE experience, but actually the VS2010 VB.NET experience.]

Either use Expression as @BenVoigt suggests, or don't use anonymous lambdas for your predicates: (VB.NET answer: Use Functions named by you and specify them with the AddressOf operator.)

C# answer is something like: declare explicit functions named by you and specify the function name when assigning the predicate.

Here is my test VB.NET code that confirms at least one way of dynamically creating predicates can be named successfully. In the VB.NET IDE these are easily seen by name.

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

Upvotes: 2

Andrej Slivko
Andrej Slivko

Reputation: 1256

if you mean that in such example

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

you would like to debug i + 1 part then you can put your mouse cursor (caret) somewhere at i + 1 and press F9 that will add a breakpoint in that expression

Upvotes: 0

Related Questions