Важное различие должно быть сделано здесь.
Большинство ответов здесь относится к 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 является реализация словаря на ViewDataDicti onary, здесь:
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.
@CodeInChaos: Обратите внимание, что отображаемый код не проверяет значение 'data.myProperty'; он проверяет, что возвращает 'typeof data.myProperty'. Правильно, что 'data.myProperty' может существовать и быть установлен в' undefined', но в этом случае 'typeof' вернет нечто, отличное от' 'undefined ''. Так что этот код действительно работает. –