EDIT例外が
を私は例外私はLINQの式を作成しようとする任意の時間を取得していますクラスまたはモジュール内のローカルに定義されたデリゲート(またはラムダ)または関数への呼び出しを含むメソッドからの呼び出し。
私は2つのパラメータ(デリゲートと整数)を取り、それは結果を取得するために使用するLINQ MethodCallExpression
を作成する関数持っている:私はエラーなしでこのコードを実行することができます
Public Delegate Function CompareTwoIntegerFunction(ByVal i1 As Integer, ByVal i2 As Integer) As Boolean
Public Function Test(ByVal pFunc As CompareTwoIntegerFunction, ByVal i1 As Integer, ByVal i2 As Integer) As Boolean
Dim lParamExpression As ParameterExpression = Expression.Parameter(GetType(Integer), "i")
Dim lConstExpr As ConstantExpression = Expression.Constant(i1, GetType(Integer))
Dim lMatcher As CompareTwoIntegerFunction = pFunc
' *** This line throws the exception (line 17)
Dim lMatcherExpr As MethodCallExpression = Expression.Call(lMatcher.Method, lParamExpression, lConstExpr)
' Now use the expression and get the result
Dim lFunc As Func(Of Integer, Boolean) = (Expression.Lambda(Of Func(Of Integer, Boolean))(lMatcherExpr, lParamExpression)).Compile
Return lFunc(i2)
End Function
をこのテストでは:
Dim lMatchedPass1 As Boolean = Test(Function(a, b) a = b, 10, 10)
私も空想取得し、このような何か行うことができます。
Dim lMatchedPass2 As Boolean = Test(Function(a, b) (Function(c As Integer) c + 1)(a) = b, 10, 9)
を
Dim ChildFunc As Func(Of Integer, Integer) = Function(s As Integer) s + 1
Dim MatchedFail1 As Boolean = Test(Function(a, b) (ChildFunc(a)) = b, 10, 9)
例外メッセージ:
Exception: [2011 Jun 23 (Thu) 10:25:29 AM] [ System.Core ]
Value cannot be null.
Parameter name: instance
at System.Linq.Expressions.Expression.ValidateCallArgs(Expression instance, MethodInfo method, ReadOnlyCollection`1& arguments)
at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments)
at System.Linq.Expressions.Expression.Call(MethodInfo method, Expression[] arguments)
at DataManager`1.Test(CompareTwoIntegerFunction pFunc, Int32 i1, Int32 i2) in DataManager.vb:line 17
at DataManager`1..ctor() in DataManager.vb:line 27
Called from: Void ValidateCallArgs(System.Linq.Expressions.Expression, System.Reflection.MethodInfo, System.Collections.ObjectModel.ReadOnlyCollection`1[System.Linq.Expressions.Expression] ByRef)
私はMatchTest2
は大丈夫ですが、MatchFail1
が問題である理由を理解したい、私はこのような何かをしようとすると210
はしかし、その後、私は例外を取得します。
注1:上記の例では定数とパラメータを使用していますが、2つの定数または2つのパラメータで同じ結果が得られます。私は、名前付き代理人型を無名関数定義に置き換えることによって例外を得ることもできます。
注2:
Dim lMatcherExpr As MethodCallExpression = Expression.Call(Nothing, pFunc.Method, lParamExpression, lConstExpr)
注3: 私がいることを見つけた 私はこのように、Expression.Call
ラインにインスタンスパラメータとしてNothing
を追加し、成功せず、試してみました上記のコードで私の "子関数"をモジュールに移動したり、クラス内の "共有"関数にすることで問題を "修正"できます。これは子関数をパラメータとして渡すことができるため、非常に現実的な解決策ではありませんが、自明ではありません。言い換えれば
、私の目標は、このような何かを行うことです。
Public Function RunTestWithChildFunction(ByVal a As Integer, ByVal b As Integer, ByVal ChildFunc As Func(Of Integer, Integer, Boolean)) As Boolean
Return Test(Function(x, y) ChildFunc(x, y), a, b)
End Function
Public Function EqualityCheck(ByVal a As Integer, ByVal b As Integer) As Boolean
Return a = b
End Function
Public Sub DoTest
Dim lMatchedFail2 As Boolean = RunTestWithChildFunction(10, 10, AddressOf EqualityCheck)
End
アドレスは(私が手RunCheckWithChildFunction
にByVal
を渡されるため、このコードではEqualityCheck
に「共有」を追加しても問題が解決しません私がそれを渡そうとするとコンパイル失敗ByRef
)。