10

在调试模式下,如果我将鼠标悬停在谓词上,我看到的只是一些类型名称和一些难以理解的符号。这使得调试代码变得非常困难,例如要知道某个变量所持有的谓词。我通常使用 lambda 表达式分配这个谓词值。有什么方法可以了解谓词包含的内容吗?

例如,如果我有一个Predicate<object> myPred或多个List<Predicate<object>> predList变量,如何在运行时调试 myPred 的值或 predList 包含的值?

4

3 回答 3

5

你可能想要Expression<Predicate<T>>. 它可以转换为Predicate<T>以便调用它,但保留有关 lambda 结构的信息。

于 2011-06-09T15:43:46.817 回答
2

【我没查过C# IDE体验,其实是VS2010 VB.NET体验。】

要么Expression按照@BenVoigt 的建议使用,要么不要将匿名 lambda 用于您的谓词:(VB.NET 回答:使用Functions由您命名并使用AddressOf运算符指定它们。)

C# 的答案类似于:声明由您命名的显式函数,并在分配谓词时指定函数名称。

这是我的测试 VB.NET 代码,它确认至少可以成功命名一种动态创建谓词的方法。在 VB.NET IDE 中,这些名称很容易看到。

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
于 2011-06-09T18:33:45.140 回答
-1

如果你的意思是在这样的例子中

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

您想调试 i + 1 部分,然后您可以将鼠标光标(插入符号)放在 i + 1 的某处,然后按 F9 将在该表达式中添加一个断点

于 2011-06-09T14:39:51.360 回答