动态+泛型似乎在Microsoft.CSharp.dll中导致NullReferenceException

时间:2015-08-05 15:08:23

标签: c# .net generics visual-studio-2015 windows-10

我遇到了一个用于检查方法参数的实用程序类的问题。它使用dynamic关键字作为泛型类型参数很多。有System.NullReferenceException抛出,我不明白。 该异常具有以下堆栈跟踪:

(我为相当长的摘录道歉,但对我来说似乎有必要......)

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#

Visual Studio Exception assistent showing the NullReferenceException

我简化了代码,以便您可以自己查看和测试:

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
    }
}

如何测试:

通过在Test的实例上调用ProblemClassA来测试它,例如:

new ProblemClassA().Test("This is a test", new object());

有人可以向我解释为什么会抛出异常吗?

提前致谢!

0 个答案:

没有答案