An important distinction needs to be made here.
Most of the answers here are specific to the ExpandoObject which is mentioned in the question. But a common usage (and reason to land on this question when searching) is when using the ASP.Net MVC ViewBag. That's a custom implementation/subclass of DynamicObject, which won't throw an Exception when you check any arbitrary property name for null. Suppose you might declare a property like:
@{
ViewBag.EnableThinger = true;
}
Then suppose you wanted to check its value, and whether it's even set - whether it exists. The following is valid, will compile, won't throw any exceptions, and gives you the right answer:
if (ViewBag.EnableThinger != null && ViewBag.EnableThinger)
{
// Do some stuff when EnableThinger is true
}
Now get rid of the declaration of EnableThinger. Same code compiles and runs properly. No need for reflection.
Unlike ViewBag, ExpandoObject will throw if you check for null on a property that doesn't exist. In order to get MVC ViewBag's gentler functionality out of your dynamic
objects, you'll need to use an implementation of dynamic that doesn't throw.
You could simply use the exact implementation in MVC ViewBag:
. . .
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = ViewData[binder.Name];
// since ViewDataDictionary always returns a result even if the key does not exist, always return true
return true;
}
. . .
https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/DynamicViewDataDictionary.cs
You can see it being tied into MVC Views here, in MVC ViewPage:
http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/ViewPage.cs
The key to DynamicViewDataDictionary's graceful behavior is the Dictionary implementation on ViewDataDictionary, here:
public object this[string key]
{
get
{
object value;
_innerDictionary.TryGetValue(key, out value);
return value;
}
set { _innerDictionary[key] = value; }
}
https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/ViewDataDictionary.cs
In other words, it always returns a value for all keys, regardless of what's in it - it simply returns null when nothing's there. But, ViewDataDictionary has the burden of being tied to MVC's Model, so it's better to strip out just the graceful dictionary parts for use outside MVC Views.
It's too long to really post all the guts here - most of it just implementing IDictionary - but here's a dynamic object (class DDict
) that doesn't throw for null checks on properties that haven't been declared, on Github:
https://github.com/b9chris/GracefulDynamicDictionary
If you just want to add it to your project via NuGet, its name is GracefulDynamicDictionary.
data.myProperty
; it checks whattypeof data.myProperty
returns. It is correct thatdata.myProperty
may exist and be set toundefined
, but in that case,typeof
will return something other than"undefined"
. So this code does work. – Blench