tipo tiempo que programacion ejecucion crear clase anonimas c# dynamic expandoobject

tiempo - tipo dynamic c#



¿Cómo detectar si una propiedad existe en un ExpandoObject? (10)

¿Por qué no quieres usar Reflection para establecer el tipo de properyes? Me gusta esto

dynamic v = new Foo(); Type t = v.GetType(); System.Reflection.PropertyInfo[] pInfo = t.GetProperties(); if (Array.Find<System.Reflection.PropertyInfo>(pInfo, p => { return p.Name == "PropName"; }). GetValue(v, null) != null)) { //PropName initialized }

En JavaScript, puede detectar si una propiedad se define utilizando la palabra clave indefinida:

if( typeof data.myProperty == "undefined" ) ...

¿Cómo harías esto en C # usando la palabra clave dinámica con un ExpandoObject y sin lanzar una excepción?


ACTUALIZADO: puede usar delegados e intentar obtener un valor de la propiedad del objeto dinámico si existe. Si no hay una propiedad, simplemente atrapa la excepción y devuelve falso.

Echa un vistazo, funciona bien para mí:

class Program { static void Main(string[] args) { dynamic userDynamic = new JsonUser(); Console.WriteLine(IsPropertyExist(() => userDynamic.first_name)); Console.WriteLine(IsPropertyExist(() => userDynamic.address)); Console.WriteLine(IsPropertyExist(() => userDynamic.last_name)); } class JsonUser { public string first_name { get; set; } public string address { get { throw new InvalidOperationException("Cannot read property value"); } } } static bool IsPropertyExist(GetValueDelegate getValueMethod) { try { //we''re not interesting in the return value. What we need to know is whether an exception occurred or not getValueMethod(); return true; } catch (RuntimeBinderException) { // RuntimeBinderException occurred during accessing the property // and it means there is no such property return false; } catch { //property exists, but an exception occurred during getting of a value return true; } } delegate string GetValueDelegate(); }

El resultado del código es el siguiente:

True True False


Este método de extensión verifica la existencia de una propiedad y luego devuelve el valor o nulo. Esto es útil si no desea que sus aplicaciones arrojen excepciones innecesarias, al menos las que puede ayudar.

public static object Value(this ExpandoObject expando, string name) { var expandoDic = (IDictionary<string, object>)expando; return expandoDic.ContainsKey(name) ? expandoDic[name] : null; }

Si puede usarse como tal:

// lookup is type ''ExpandoObject'' object value = lookup.Value("MyProperty");

o si su variable local es ''dinámica'', primero tendrá que enviarla a ExpandoObject.

// lookup is type ''dynamic'' object value = ((ExpandoObject)lookup).Value("PropertyBeingTested");


Hace poco respondí una pregunta muy similar: ¿cómo puedo reflexionar sobre los miembros del objeto dinámico?

En breve, ExpandoObject no es el único objeto dinámico que puede obtener. La reflexión funcionaría para tipos estáticos (tipos que no implementan IDynamicMetaObjectProvider). Para los tipos que implementan esta interfaz, la reflexión es básicamente inútil. Para ExpandoObject, simplemente puede verificar si la propiedad está definida como una clave en el diccionario subyacente. Para otras implementaciones, puede ser un desafío y, a veces, la única forma es trabajar con excepciones. Para más detalles, siga el enlace de arriba.


Hola chicos, deja de usar Reflection para todo lo que cuesta un montón de ciclos de CPU.

Aquí está la solución:

public class DynamicDictionary : DynamicObject { Dictionary<string, object> dictionary = new Dictionary<string, object>(); public int Count { get { return dictionary.Count; } } public override bool TryGetMember(GetMemberBinder binder, out object result) { string name = binder.Name; if (!dictionary.TryGetValue(binder.Name, out result)) result = "undefined"; return true; } public override bool TrySetMember(SetMemberBinder binder, object value) { dictionary[binder.Name] = value; return true; } }


Prueba este

public bool PropertyExist(object obj, string propertyName) { return obj.GetType().GetProperty(propertyName) != null; }


Quería crear un método de extensión para poder hacer algo como:

dynamic myDynamicObject; myDynamicObject.propertyName = "value"; if (myDynamicObject.HasProperty("propertyName")) { //... }

... pero no puede crear extensiones en ExpandoObject acuerdo con la documentación de C # 5 (más información here ).

Así que terminé creando un ayudante de clase:

public static class ExpandoObjectHelper { public static bool HasProperty(ExpandoObject obj, string propertyName) { return ((IDictionary<String, object>)obj).ContainsKey(propertyName); } }


Se debe hacer una distinción importante aquí.

La mayoría de las respuestas aquí son específicas del ExpandoObject que se menciona en la pregunta. Pero un uso común (y razón para aterrizar en esta pregunta cuando se busca) es cuando se usa ASP.Net MVC ViewBag. Esa es una implementación / subclase personalizada de DynamicObject, que no arrojará una excepción cuando verifique cualquier nombre de propiedad arbitrario para null. Supongamos que puede declarar una propiedad como:

@{ ViewBag.EnableThinger = true; }

Luego, supongamos que desea verificar su valor, y si incluso está configurado, si existe. Lo siguiente es válido, compilará, no lanzará ninguna excepción y le dará la respuesta correcta:

if (ViewBag.EnableThinger != null && ViewBag.EnableThinger) { // Do some stuff when EnableThinger is true }

Ahora deshazte de la declaración de EnableThinger. El mismo código se compila y se ejecuta correctamente. No hay necesidad de reflexión.

A diferencia de ViewBag, ExpandoObject lanzará si comprueba null en una propiedad que no existe. Para sacar la funcionalidad más suave de MVC ViewBag de sus objetos dynamic , necesitará usar una implementación de dinámica que no arroje.

Simplemente podría usar la implementación exacta en 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

Puede ver que está vinculado a MVC Views aquí, en MVC ViewPage:

http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/ViewPage.cs

La clave del elegante comportamiento de DynamicViewDataDictionary es la implementación del diccionario en ViewDataDictionary, aquí:

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

En otras palabras, siempre devuelve un valor para todas las claves, independientemente de lo que contenga; simplemente devuelve nulo cuando no hay nada. Sin embargo, ViewDataDictionary tiene la carga de estar vinculado al Modelo de MVC, por lo que es mejor quitar solo las partes del diccionario elegantes para usar fuera de MVC Views.

Es demasiado largo para realmente publicar todas las agallas aquí, la mayoría simplemente implementando IDictionary, pero aquí hay un objeto dinámico que no arroja nulos controles en propiedades que no han sido declaradas, en Github:

https://github.com/b9chris/GracefulDynamicDictionary

Si solo desea agregarlo a su proyecto a través de NuGet, su nombre es GracefulDynamicDictionary .


Según MSDN la declaración muestra que está implementando IDictionary:

public sealed class ExpandoObject : IDynamicMetaObjectProvider, IDictionary<string, Object>, ICollection<KeyValuePair<string, Object>>, IEnumerable<KeyValuePair<string, Object>>, IEnumerable, INotifyPropertyChanged

Puede usar esto para ver si un miembro está definido:

var expandoObject = ...; if(((IDictionary<String, object>)expandoObject).ContainsKey("SomeMember")) { // expandoObject.SomeMember exists. }


(authorDynamic as ExpandoObject).Any(pair => pair.Key == "YourProp");