简体   繁体   中英

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?

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.

[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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM