在调试模式中,如果我将鼠标悬停在谓词上,我看到的只是一些类型名称和一些不可理解的符号。这使得调试代码变得非常困难,例如,要知道某个变量包含的谓词是什么。我通常使用lambda表达式为这个谓词赋值。有什么方法可以了解谓词包含的内容吗?
例如,如果我有一个Predicate<object> myPred
变量或List<Predicate<object>> predList
变量,我如何在运行时调试myPred的值或predList包含的值?
您可能想要Expression<Predicate<T>>
。它可以转换为Predicate<T>
以便调用它,但保留有关lambda结构的信息。
[我没有检查C#IDE的体验,但实际上检查了VS2010 VB.NET的体验。]
按照@BenVoigt的建议使用Expression
,或者不要对谓词使用匿名lambdas:(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
如果你的意思是在这样的例子
new List<int>()
.Select(i => i + 1);
如果你想调试i+1部分,那么你可以把鼠标光标(插入符号)放在i+1的某个地方,然后按F9键,这将在表达式