I wonder if someone could explain why in this code
public class SomeClass
{
public T GenericMethod<T>(dynamic value)
{
return (T)value;
}
}
the 'return value;' statement throws an null reference exception when called with:
new SomeClass().GenericMethod<object>(new object()); // throws System.NullReferenceException
It works as expected when called with:
new SomeClass().GenericMethod<string>("SomeString"); // returns SomeString
new SomeClass().GenericMethod<object>("SomeString"); // returns SomeString
Note: The following compiles and runs just fine
public class SomeOtherClass
{
public T GenericMethod<T>(object value)
{
return (T)value;
}
}
The stacktrace:
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.CSharp.RuntimeBinder.ExpressionTreeCallRewriter.GenerateLambda(EXPRCALL pExpr)
at Microsoft.CSharp.RuntimeBinder.Semantics.ExprVisitorBase.Visit(EXPR pExpr)
at Microsoft.CSharp.RuntimeBinder.ExpressionTreeCallRewriter.Rewrite(TypeManager typeManager, EXPR pExpr, IEnumerable`1 listOfParameters)
at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.BindCore(DynamicMetaObjectBinder payload, IEnumerable`1 parameters, DynamicMetaObject[] args, DynamicMetaObject& deferredBinding)
at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.Bind(DynamicMetaObjectBinder payload, IEnumerable`1 parameters, DynamicMetaObject[] args, DynamicMetaObject& deferredBinding)
at Microsoft.CSharp.RuntimeBinder.BinderHelper.Bind(DynamicMetaObjectBinder action, RuntimeBinder binder, IEnumerable`1 args, IEnumerable`1 arginfos, DynamicMetaObject onBindingError)
at Microsoft.CSharp.RuntimeBinder.CSharpConvertBinder.FallbackConvert(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
at System.Dynamic.DynamicMetaObject.BindConvert(ConvertBinder binder)
at System.Dynamic.DynamicMetaObjectBinder.Bind(Object[] args, ReadOnlyCollection`1 parameters, LabelTarget returnLabel)
at System.Runtime.CompilerServices.CallSiteBinder.BindCore[T](CallSite`1 site, Object[] args)
at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
A NullReferenceException happens when you try to access a reference variable that isn't referencing any object. If a reference variable isn't referencing an object, then it'll be treated as null .
A NullReferenceException exception is thrown when you try to access a member on a type whose value is null . A NullReferenceException exception typically reflects developer error and is thrown in the following scenarios: You've forgotten to instantiate a reference type.
Use Null Coalescing to Avoid NullReferenceExceptions It works with all nullable data types. The following code throws an exception without the null coalescing. Adding “?? new List<string>()” prevents the “Object reference not set to an instance of an object” exception.
In order to check a dynamic for null, you should cast it as an object. For example, dynamic post = SomeMethod(); if (post. modified == null){ //could return errors. }
It appears it's a bug first reported in 2012 but still apparently not fixed (as of May 24th 2016)
Update
As the marked duplicate indicates this is a known bug in the .NET runtime.
object
you get the compiler error
Cannot implicitly convert type 'object' to 'T'. An explicit conversion exists (are you missing a cast?)
Since by adding dynamic
this casting is done at run-time, this implicit conversion error manifests itself differently at run-time with a vague NullReferenceException
in the run-time bindings.
I'm not an expert in the inner workings of the DLR, but I suspect that an object passed as a dynamic
value is not really a pure object
at run-time. I suspect that it's some sort of wrapper around object
, and thus can't be implicitly cast to object at run-time.
An explicit reference cast
return (T)(object)value;
will not generate that error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With