Why is casting a dynamic of type object to object throwing a null reference exception?
I agree with the other answerers who say that this looks like a bug. Specifically it appears to be a bug in C# runtime binding layer, though I have not investigated it thoroughly.
I apologize for the error. I'll report it to the C# 5 testing team and we'll see if it has already been reported and fixed in C# 5. (It reproduces in the recent beta release, so it is unlikely that it has already been reported and fixed.) If not, a fix is unlikely to make it into the final release. In that case we'll consider it for a possible servicing release.
Thanks for bringing this to our attention. If you feel like entering a Connect issue to track it, feel free to do so and please include a link to this StackOverflow question. If you don't, no problem; the test team will know about it either way.
This is an issue with how dynamic works - the runtime binder has an issue with conversions from System.Object
, but in practice, is really not an issue.
I suspect this is because dynamic
, at runtime, is itself always System.Object
. The C# Language Spec in 4.7 states: "The type dynamic is indistinguishable from object at run-time." As such, any object used as dynamic is just stored as an object.
When you put an actual instance of System.Object
into a dynamic, something is occuring within the runtime binding resolution which causes a null reference exception.
However, any other type that isn't System.Object
works - even reference types and the like, without flaws. As such, this should provide you the proper behavior, since there really are no reasons to create an instance of System.Object
itself which would be passed around - you'd always want some subclass with other type information.
As soon as you use any "real" type, this works fine. For exmaple, the following works, even though it's passed and treated as Object
:
public class Program
{
public static T TryGetArrayValue<T>(object[] array_, int index_)
{
dynamic boxed = array_[index_];
return (T)boxed;
}
private static void Main()
{
int p = 3;
object a = p;
var objects = new[] { a, 4.5 };
// This works now, since the object is pointing to a class instance
object v = TryGetArrayValue<object>(objects, 0);
Console.WriteLine(v);
// These both also work fine...
double d = TryGetArrayValue<double>(objects, 1);
Console.WriteLine(d);
// Even the "automatic" int conversion works now
int i = TryGetArrayValue<int>(objects, 1);
Console.WriteLine(i);
Console.ReadKey();
}
}