una - string c# ejemplos
Obtener valor de la propiedad dinámica de c#a través de una cadena (8)
d.GetType (). GetProperty ("value2")
devuelve un objeto PropertyInfo.
Entonces, hazlo
propertyInfo.GetValue(d)
Me gustaría acceder al valor de una propiedad dynamic
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 cadena? En javascript, podría hacer d ["value2"] para acceder al valor ("random"), pero no estoy seguro de cómo hacer esto con c # y reflection. 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!
El método más fácil para obtener un setter
y un getter
para una propiedad que funciona para cualquier tipo, incluyendo dynamic
y ExpandoObject
es usar FastMember
que también es el método más rápido (usa Emit).
Puede obtener un TypeAccessor
basado en un tipo determinado o un ObjectAccessor
basado en una instancia de un tipo determinado.
Ejemplo:
var staticData = new Test { Id = 1, Name = "France" };
var objAccessor = ObjectAccessor.Create(staticData);
objAccessor["Id"].Should().Be(1);
objAccessor["Name"].Should().Be("France");
var anonymous = new { Id = 2, Name = "Hilton" };
objAccessor = ObjectAccessor.Create(anonymous);
objAccessor["Id"].Should().Be(2);
objAccessor["Name"].Should().Be("Hilton");
dynamic expando = new ExpandoObject();
expando.Id = 3;
expando.Name = "Monica";
objAccessor = ObjectAccessor.Create(expando);
objAccessor["Id"].Should().Be(3);
objAccessor["Name"].Should().Be("Monica");
var typeAccessor = TypeAccessor.Create(staticData.GetType());
typeAccessor[staticData, "Id"].Should().Be(1);
typeAccessor[staticData, "Name"].Should().Be("France");
typeAccessor = TypeAccessor.Create(anonymous.GetType());
typeAccessor[anonymous, "Id"].Should().Be(2);
typeAccessor[anonymous, "Name"].Should().Be("Hilton");
typeAccessor = TypeAccessor.Create(expando.GetType());
((int)typeAccessor[expando, "Id"]).Should().Be(3);
((string)typeAccessor[expando, "Name"]).Should().Be("Monica");
Esta es la manera en que obtuve el valor de un valor de propiedad de un dinámico:
public dynamic Post(dynamic value)
{
try
{
if (value != null)
{
var valorCampos = "";
foreach (Newtonsoft.Json.Linq.JProperty item in value)
{
if (item.Name == "valorCampo")//property name
valorCampos = item.Value.ToString();
}
}
}
catch (Exception ex)
{
}
}
GetProperty / GetValue no funciona para datos Json, siempre genera una excepción nula, sin embargo, puede probar este enfoque:
Serialice su objeto usando JsonConvert:
var z = Newtonsoft.Json.JsonConvert.DeserializeObject(Convert.ToString(request));
Luego acceda directamente devolviéndolo a la secuencia:
var pn = (string)z["DynamicFieldName"];
Puede funcionar correctamente aplicando Convert.ToString (solicitud) ["DynamicFieldName"], pero no lo he probado.
La mayoría de las veces, cuando solicita un objeto dinámico, obtiene un ExpandoObject (no en el ejemplo anterior de la pregunta, anónimo pero estático, pero menciona JavaScript y el analizador JSON JsonFx elegido, por ejemplo, genera ExpandoObjects).
Si su dinámica es, de hecho, un ExpandoObject, puede evitar la reflexión transfiriéndola a IDictionary, como se describe en http://msdn.microsoft.com/en-gb/library/system.dynamic.expandoobject.aspx .
Una vez que has lanzado a IDictionary, tienes acceso a métodos útiles como .Item y .ContainsKey
Una vez que tenga su PropertyInfo
(de GetProperty
), debe llamar a GetValue
y pasar la instancia de la que desea obtener el valor. En tu caso:
d.GetType().GetProperty("value2").GetValue(d, null);
Dynamitey es una biblioteca .net std
código abierto, que puedes llamar como la palabra clave dynamic
, pero usando una cadena para el nombre de la propiedad en lugar de que el compilador lo haga por ti, y termine siendo igual a la reflexión en sentido horario (que es no tan rápido como usar la palabra clave dinámica, pero esto se debe a la sobrecarga adicional del almacenamiento en caché de forma dinámica, donde el compilador almacena en caché estáticamente).
Dynamic.InvokeGet(d,"value2");
public static object GetProperty(object target, string name)
{
var site = System.Runtime.CompilerServices.CallSite<Func<System.Runtime.CompilerServices.CallSite, object, object>>.Create(Microsoft.CSharp.RuntimeBinder.Binder.GetMember(0, name, target.GetType(), new[]{Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(0,null)}));
return site.Target(site, target);
}
Agregue referencia a Microsoft.CSharp. Funciona también para tipos dinámicos y propiedades y campos privados.
Editar : Mientras que este enfoque funciona, hay un método casi 20 veces más rápido desde el ensamblado Microsoft.VisualBasic.dll :
public static object GetProperty(object target, string name)
{
return Microsoft.VisualBasic.CompilerServices.Versioned.CallByName(target, name, CallType.Get);
}