This project has moved. For the latest updates, please go here.

Null reference when calling compiled LambdaExpression

Dec 14, 2010 at 1:13 PM

I'm trying to call a compiled LambdaExpression with the following code:

LambdaExpression exp = CreateExpression();
MethodInfo method = exp.Compile().Method;

method.DelegateForCallStaticMethod()(parameter);

But I receive a NullReferenceException when calling the delegate returned by Fasterflect. I've traced the exception down to the GetHashCode mehtod of the CallInfo class. It seems that the TargetType (which is initialized with the DeclaringType of the MethodInfo) property is null. I believe that DeclaringType should be null because the method is created at runtime and is not declared in any type.

Is there another way of calling a MethodInfo in this scenario or, even better, the Delegate generated by the LambdaExpression.Compile method?

Coordinator
Dec 14, 2010 at 4:05 PM

If you're creating the method using expression trees and .Compile, why not just hold on to the result and use that?

var param = Expression.Parameter( typeof(int), "x" );
var expression = Expression.Lambda<Func<int, int>>(
    Expression.Add( param, Expression.Constant( 1 ) ),
    new List<ParameterExpression> { param } );
var func = expression.Compile();
var two = func( 1 );
Assert.AreEqual( 2, two );

Dec 15, 2010 at 11:35 AM

What happens is that i'm not using a Expression<Func<T, TResult>>. I'm using LambdaExpression and when i call .Compile the return is a Delegate.

I could cast the Delegate to a Func<T, TResult> but since its the user that chooses what "T" means i don't know at compile time the correct type to cast the Delegate and that's why i'm trying to use fastreflect to call the Delegate dynamically, since i want to avoid using DynamicInvoke which has bad performance.

Coordinator
Dec 15, 2010 at 9:40 PM

Actually, I think DynamicInvoke has pretty decent performance. It's slower than using a cached Fasterflect delegate but it's still pretty darn fast, and thus unlikely to be a bottleneck in your application. 

See this post for some numbers: http://bloggingabout.net/blogs/vagif/archive/2010/04/02/don-t-use-activator-createinstance-or-constructorinfo-invoke-use-compiled-lambda-expressions.aspx

That said, if you post a complete example of what you'd like the library to do, preferably in "unit test format" like my snippet above, then I'll have a look at making the unit test work.