Me gustaría acceder al valor de una dynamicpropiedad de C # con una cadena:
dynamic d = new { value1 = "some", value2 = "random", value3 = "value" };
¿Cómo puedo obtener el valor de d.value2 ("random") si solo tengo "value2" como una cadena? En javascript, podría hacer d ["value2"] para acceder al valor ("random"), pero no estoy seguro de cómo hacerlo con c # y la reflexión. Lo más cerca que he venido es esto:
d.GetType().GetProperty("value2") ... pero no sé cómo obtener el valor real de eso.
Como siempre, gracias por tu ayuda!

Respuestas:
Una vez que tenga su
PropertyInfo(desdeGetProperty), debe llamarGetValuey pasar la instancia de la que desea obtener el valor. En tu caso:fuente
'd.GetType().GetProperty("value2").GetValue(d)' threw an exception of type 'System.Reflection.TargetInvocationException' dynamic {System.Reflection.TargetInvocationException}en la ventana del reloj con eso ...?new {}crea un tipo anónimo real con propiedades definidas, llamar a GetType / GetProperty tiene sentido, pero qué pasa con ExpandoObject, que si llama a GetType, obtendrá un tipo que tiene las propiedades de ExpandoObject, pero no necesariamente sus propiedades dinámicas.Agregar referencia a Microsoft.CSharp. Funciona también para tipos dinámicos y propiedades y campos privados.
Editar : Si bien este enfoque funciona, hay un método casi 20 veces más rápido del ensamblado Microsoft.VisualBasic.dll :
fuente
den la pregunta).CallSitecódigo frente alCallByNamecódigo, ¿comparó los dos al almacenar en caché laCallSiteinstancia? Sospecho que el costo de su primer método es casi puramente la activación deBinderyCallSite, no la invocación deTarget()Dynamitey es una
.net stdbiblioteca de código abierto , que le permite llamarla como ladynamicpalabra clave, pero usando una cadena para el nombre de la propiedad en lugar del compilador que lo hace por usted, y termina siendo igual a la velocidad de reflexión (que no es tan rápido) como el uso de la palabra clave dinámica, pero esto se debe a la sobrecarga adicional de almacenamiento en caché de forma dinámica, donde el compilador almacena en caché de forma estática).fuente
El método más fácil para obtener a
settery agetterpara una propiedad que funciona para cualquier tipo, incluidodynamicyExpandoObjectes usar,FastMemberque también es el método más rápido (usa Emit).Puede obtener una
TypeAccessorbase de un tipo determinado o unaObjectAccessorbase de una instancia de un tipo determinado.Ejemplo:
fuente
La mayoría de las veces, cuando solicita un objeto dinámico, obtiene un Objeto de Expando (no en el ejemplo de la pregunta anónimo, pero estáticamente escrito anteriormente, pero menciona JavaScript y mi analizador JSON elegido JsonFx, por ejemplo, genera ExpandoObjects).
Si su dinámica es, de hecho, un Objeto de Expando, puede evitar la reflexión lanzándola a IDictionary, como se describe en http://msdn.microsoft.com/en-gb/library/system.dynamic.expandoobject.aspx .
Una vez que ha enviado a IDictionary, tiene acceso a métodos útiles como .Item y .ContainsKey
fuente
Int64? i = data.value; //data is ExpandoObjectbuscaría automáticamente y llamaría al operador implícito. Por otro lado, si tuviera que usar IDictionary para probar si existe el campo "valor", obtendría un objeto que no se lanzará sin error a Int64.GetProperty / GetValue no funciona para datos Json, siempre genera una excepción nula, sin embargo, puede probar este enfoque:
Serialice su objeto usando JsonConvert:
Luego, acceda directamente a él, volviéndolo a la cadena:
Puede funcionar directamente aplicando Convert.ToString (solicitud) ["DynamicFieldName"], sin embargo, no lo he probado.
fuente
new JavaScriptSerializer().Deserialize<object>(json);para llegar a las "propiedades" de la manera que sugiriódevuelve un objeto PropertyInfo.
Entonces hazlo
fuente
GetValue(d)necesidad debe serGetValue(d,null)Esta es la forma en que obtuve el valor de un valor de propiedad de una dinámica:
fuente
Para obtener propiedades del documento dinámico cuando
.GetType()regresanull, intente esto:fuente
En .Net core 3.1 puedes probar así
fuente
Similar a la respuesta aceptada, también puede intentar en
GetFieldlugar deGetProperty.d.GetType().GetField("value2").GetValue(d);Dependiendo de cómo
Typese implementó el actual , esto puede funcionar cuando GetProperty () no lo hace e incluso puede ser más rápido.fuente