Здесь необходимо провести важное различие.
Большинство ответов здесь относятся только к ExpandoObject, который упоминается в вопросе. Но обычное использование (и причина для поиска этого вопроса при поиске) - использование ASP.Net MVC ViewBag. Это пользовательская реализация / подкласс DynamicObject, которая не будет генерировать исключение, когда вы проверяете любое произвольное имя свойства на null. Предположим, вы можете объявить свойство как:
@{
ViewBag.EnableThinger = true;
}
Тогда предположим, что вы хотели проверить его значение, и было ли оно установлено - существует ли оно. Следующее является действительным, скомпилируется, не выдаст никаких исключений и даст правильный ответ:
if (ViewBag.EnableThinger != null && ViewBag.EnableThinger)
{
// Do some stuff when EnableThinger is true
}
Теперь избавимся от объявления EnableThinger. Тот же код компилируется и работает правильно. Не нужно размышлять.
В отличие от ViewBag, ExpandoObject будет выдавать, если вы проверяете на null свойство, которое не существует. Чтобы получить более мягкую функциональность MVC ViewBag из ваших dynamic
объектов, вам нужно использовать динамическую реализацию, которая не генерирует.
Вы можете просто использовать точную реализацию в 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
Вы можете увидеть его привязанным к MVC-представлениям здесь, в MVC ViewPage:
http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/ViewPage.cs
Ключом к изящному поведению DynamicViewDataDictionary является реализация словаря в ViewDataDictionary, здесь:
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
Другими словами, он всегда возвращает значение для всех ключей, независимо от того, что в нем, - он просто возвращает ноль, когда там ничего нет. Но ViewDataDictionary имеет бремя привязки к модели MVC, поэтому лучше исключить только изящные части словаря для использования вне MVC Views.
Слишком долго, чтобы действительно публиковать здесь все кишки - большинство из них просто реализуют IDictionary - но вот динамический объект, который не генерирует нулевые проверки свойств, которые не были объявлены, на Github:
https://github.com/b9chris/GracefulDynamicDictionary
Если вы просто хотите добавить его в свой проект через NuGet, его имя будет GracefulDynamicDictionary .