I encountered an issue with an utility class that is used to check method parameters. It uses the dynamic
keyword as generic type parameter a lot. There is a System.NullReferenceException
thrown, that I don't understand.
The exception has the following stacktrace:
(I apologize for the rather long excerpt, but it seems necessary to me...)
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.ExpressionTreeCallRewriter.GenerateLambda(Microsoft.CSharp.RuntimeBinder.Semantics.EXPRCALL) Unknown
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.ExpressionTreeCallRewriter.VisitCALL(Microsoft.CSharp.RuntimeBinder.Semantics.EXPRCALL) Unknown
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.Semantics.ExprVisitorBase.Dispatch(Microsoft.CSharp.RuntimeBinder.Semantics.EXPR) Unknown
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.Semantics.ExprVisitorBase.Visit(Microsoft.CSharp.RuntimeBinder.Semantics.EXPR) Unknown
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.ExpressionTreeCallRewriter.Rewrite(Microsoft.CSharp.RuntimeBinder.Semantics.TypeManager, Microsoft.CSharp.RuntimeBinder.Semantics.EXPR, System.Collections.Generic.IEnumerable<System.Linq.Expressions.Expression>) Unknown
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.RuntimeBinder.CreateExpressionTreeFromResult(System.Collections.Generic.IEnumerable<System.Linq.Expressions.Expression>, Microsoft.CSharp.RuntimeBinder.RuntimeBinder.ArgumentObject[], Microsoft.CSharp.RuntimeBinder.Semantics.Scope, Microsoft.CSharp.RuntimeBinder.Semantics.EXPR) Unknown
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.RuntimeBinder.BindCore(System.Dynamic.DynamicMetaObjectBinder, System.Collections.Generic.IEnumerable<System.Linq.Expressions.Expression>, System.Dynamic.DynamicMetaObject[], out System.Dynamic.DynamicMetaObject) Unknown
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.RuntimeBinder.Bind(System.Dynamic.DynamicMetaObjectBinder, System.Collections.Generic.IEnumerable<System.Linq.Expressions.Expression>, System.Dynamic.DynamicMetaObject[], out System.Dynamic.DynamicMetaObject) Unknown
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.BinderHelper.Bind(System.Dynamic.DynamicMetaObjectBinder, Microsoft.CSharp.RuntimeBinder.RuntimeBinder, System.Collections.Generic.IEnumerable<System.Dynamic.DynamicMetaObject>, System.Collections.Generic.IEnumerable<Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>, System.Dynamic.DynamicMetaObject) Unknown
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.CSharpConvertBinder.FallbackConvert(System.Dynamic.DynamicMetaObject, System.Dynamic.DynamicMetaObject) Unknown
System.Dynamic.Runtime.dll!System.Dynamic.ConvertBinder.FallbackConvert(System.Dynamic.DynamicMetaObject) Unknown
System.Dynamic.Runtime.dll!System.Dynamic.DynamicMetaObject.BindConvert(System.Dynamic.ConvertBinder) Unknown
System.Dynamic.Runtime.dll!System.Dynamic.ConvertBinder.Bind(System.Dynamic.DynamicMetaObject, System.Dynamic.DynamicMetaObject[]) Unknown
System.Dynamic.Runtime.dll!System.Dynamic.DynamicMetaObjectBinder.Bind(object[], System.Collections.ObjectModel.ReadOnlyCollection<System.Linq.Expressions.ParameterExpression>, System.Linq.Expressions.LabelTarget) Unknown
System.Dynamic.Runtime.dll!System.Runtime.CompilerServices.CallSiteBinder.BindCore<System.Func<System.Runtime.CompilerServices.CallSite, object, object>>(System.Runtime.CompilerServices.CallSite<System.Func<System.Runtime.CompilerServices.CallSite, object, object>>, object[]) Unknown
System.Dynamic.Runtime.dll!System.Runtime.CompilerServices.CallSiteOps.Bind<System.Func<System.Runtime.CompilerServices.CallSite, object, object>>(System.Runtime.CompilerServices.CallSiteBinder, System.Runtime.CompilerServices.CallSite<System.Func<System.Runtime.CompilerServices.CallSite, object, object>>, object[]) Unknown
[Native to Managed Transition]
[Managed to Native Transition]
System.Linq.Expressions.dll!System.Linq.Expressions.Interpreter.MethodInfoCallInstruction.InvokeWorker(object[]) Unknown
System.Linq.Expressions.dll!System.Linq.Expressions.Interpreter.MethodInfoCallInstruction.Invoke(object[]) Unknown
System.Linq.Expressions.dll!System.Linq.Expressions.Interpreter.MethodInfoCallInstruction.Run(System.Linq.Expressions.Interpreter.InterpretedFrame) Unknown
System.Linq.Expressions.dll!System.Linq.Expressions.Interpreter.Interpreter.Run(System.Linq.Expressions.Interpreter.InterpretedFrame) Unknown
System.Linq.Expressions.dll!System.Linq.Expressions.Interpreter.LightLambda.Run(object[]) Unknown
System.Linq.Expressions.dll!System.Linq.Expressions.Interpreter.CallInstruction.InterpretLambdaInvoke(System.Linq.Expressions.Interpreter.LightLambda, object[]) Unknown
System.Linq.Expressions.dll!System.Linq.Expressions.Interpreter.MethodInfoCallInstruction.InvokeWorker(object[]) Unknown
System.Linq.Expressions.dll!System.Linq.Expressions.Interpreter.MethodInfoCallInstruction.Invoke(object[]) Unknown
System.Linq.Expressions.dll!System.Linq.Expressions.Interpreter.MethodInfoCallInstruction.Run(System.Linq.Expressions.Interpreter.InterpretedFrame) Unknown
System.Linq.Expressions.dll!System.Linq.Expressions.Interpreter.Interpreter.Run(System.Linq.Expressions.Interpreter.InterpretedFrame) Unknown
System.Linq.Expressions.dll!System.Linq.Expressions.Interpreter.LightLambda.Run(object[]) Unknown
[Lightweight Function]
ProblematicUsageOfGenericsAndDynamic.exe!ProblematicUsageOfGenericsAndDynamic.ProblemClassA.Trouble<object>(System.Linq.Expressions.Expression<System.Func<object>>, out object) C#
ProblematicUsageOfGenericsAndDynamic.exe!ProblematicUsageOfGenericsAndDynamic.ProblemClassB.Test(string, object) C#
ProblematicUsageOfGenericsAndDynamic.exe!ProblematicUsageOfGenericsAndDynamic.MainPage.MainPage() C#
ProblematicUsageOfGenericsAndDynamic.exe!ProblematicUsageOfGenericsAndDynamic.ProblematicUsageOfGenericsAndDynamic_XamlTypeInfo.XamlTypeInfoProvider.Activate_0_MainPage() C#
ProblematicUsageOfGenericsAndDynamic.exe!ProblematicUsageOfGenericsAndDynamic.ProblematicUsageOfGenericsAndDynamic_XamlTypeInfo.XamlUserType.ActivateInstance() C#
[Native to Managed Transition]
[Managed to Native Transition]
ProblematicUsageOfGenericsAndDynamic.exe!ProblematicUsageOfGenericsAndDynamic.App.OnLaunched(Windows.ApplicationModel.Activation.LaunchActivatedEventArgs) C#
I simplified the code so that you can see and test for yourself:
ProblemClassA.cs:
using System.Linq.Expressions;
public class ProblemClassA
{
private dynamic GetValue<T>(Expression<Func<T>> argument)
{
var getterLambda = Expression.Lambda<Func<dynamic>>(argument.Body);
var getter = getterLambda.Compile();
return getter();
}
public void Trouble<T>(Expression<Func<T>> argument, out T argumentValue)
{
argumentValue = this.GetValue(argument);
}
public void JustFine(Expression<Func<object>> argument, out object argumentValue)
{
argumentValue = this.GetValue(argument);
}
}
ProblemClassB.cs:
public class ProblemClassB
{
public void Test(string aString, object anObject)
{
ProblemClassA problemClassA = new ProblemClassA();
object valueString;
object valueObject;
problemClassA.JustFine(() => aString, out valueString); // Works fine
problemClassA.JustFine(() => anObject, out valueObject); // Works fine
problemClassA.Trouble(() => aString, out valueString); // Works fine as well
problemClassA.Trouble(() => anObject, out valueObject); // Throws an exception NullReferenceException
}
}
How to test:
Test it by calling Test
on an instance of ProblemClassA
, e.g.:
new ProblemClassA().Test("This is a test", new object());
Can anybody please explain to me why the exception is thrown?
Thanks in advance!