Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 296
Louis Rhys Avatar asked Jun 09 '11 14:06

Louis Rhys


2 Answers

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.

like image 71
Ben Voigt Avatar answered Oct 17 '22 03:10

Ben Voigt


[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
like image 2
Mark Hurd Avatar answered Oct 17 '22 03:10

Mark Hurd