with property name method getfields from español c# .net reflection properties

c# - property - Establecer la propiedad del objeto utilizando la reflexión.



reflection c# español (11)

Acabo de publicar un paquete Nuget que permite configurar no solo las propiedades de primer nivel sino también las propiedades anidadas en el objeto dado en cualquier profundidad.

Aquí está el paquete

Establece el valor de una propiedad de un objeto por su ruta desde la raíz.

El objeto puede ser un objeto complejo y la propiedad puede ser una propiedad anidada profunda de varios niveles o puede ser una propiedad directamente debajo de la raíz. ObjectWriter encontrará la propiedad utilizando el parámetro de ruta de la propiedad y actualizará su valor. La ruta de la propiedad son los nombres agregados de las propiedades visitadas desde la raíz hasta la propiedad del nodo final que queremos establecer, delimitadas por el parámetro de la cadena delimitadora.

Uso:

Para configurar las propiedades directamente debajo de la raíz del objeto:

Es decir. LineItem clase LineItem tiene una propiedad int llamada ItemId

LineItem lineItem = new LineItem(); ObjectWriter.Set(lineItem, "ItemId", 13, delimiter: null);

Para configurar múltiples niveles de propiedades anidadas debajo de la raíz del objeto:

Es decir. Invite clase Invite tiene una propiedad llamada State , que tiene una propiedad llamada Invite (de tipo Invite), que tiene una propiedad llamada Recipient , que tiene una propiedad llamada Id .

Para hacer las cosas aún más complejas, la propiedad State no es un tipo de referencia, es una struct .

Aquí es cómo puede establecer la propiedad Id (para el valor de cadena de "Outlook") en la parte inferior del árbol de objetos en una sola línea.

Invite invite = new Invite(); ObjectWriter.Set(invite, "State_Invite_Recipient_Id", "outlook", delimiter: "_");

¿Hay alguna forma en C # 3.5 donde pueda usar la reflexión para establecer una propiedad de objeto?

Ex:

MyObject obj = new MyObject(); obj.Name = "Value";

Quiero establecer obj.Name con reflexión. Algo como:

Reflection.SetProperty(obj, "Name") = "Value";

¿Hay alguna forma de hacer esto?


Basándome en la sugerencia de MarcGravell, he construido el siguiente método estático. El método generalmente asigna todas las propiedades coincidentes desde el objeto de origen al destino utilizando FastMember

public static void DynamicPropertySet(object source, object target) { //SOURCE var src_accessor = TypeAccessor.Create(source.GetType()); if (src_accessor == null) { throw new ApplicationException("Could not create accessor!"); } var src_members = src_accessor.GetMembers(); if (src_members == null) { throw new ApplicationException("Could not fetch members!"); } var src_class_members = src_members.Where(x => x.Type.IsClass && !x.Type.IsPrimitive); var src_class_propNames = src_class_members.Select(x => x.Name); var src_propNames = src_members.Except(src_class_members).Select(x => x.Name); //TARGET var trg_accessor = TypeAccessor.Create(target.GetType()); if (trg_accessor == null) { throw new ApplicationException("Could not create accessor!"); } var trg_members = trg_accessor.GetMembers(); if (trg_members == null) { throw new ApplicationException("Could not create accessor!"); } var trg_class_members = trg_members.Where(x => x.Type.IsClass && !x.Type.IsPrimitive); var trg_class_propNames = trg_class_members.Select(x => x.Name); var trg_propNames = trg_members.Except(trg_class_members).Select(x => x.Name); var class_propNames = trg_class_propNames.Intersect(src_class_propNames); var propNames = trg_propNames.Intersect(src_propNames); foreach (var propName in propNames) { trg_accessor[target, propName] = src_accessor[source, propName]; } foreach (var member in class_propNames) { var src = src_accessor[source, member]; var trg = trg_accessor[target, member]; if (src != null && trg != null) { DynamicPropertySet(src, trg); } } }


O puedes envolver el liner de Marc dentro de tu propia clase de extensión:

public static class PropertyExtension{ public static void SetPropertyValue(this object obj, string propName, object value) { obj.GetType().GetProperty(propName).SetValue(obj, value, null); } }

y llámalo así:

myObject.SetPropertyValue("myProperty", "myValue");

Para una buena medida, agreguemos un método para obtener un valor de propiedad:

public static object GetPropertyValue(this object obj, string propName) { return obj.GetType().GetProperty(propName).GetValue (obj, null); }


Puede probar esto cuando desee asignar en masa las propiedades de un Objeto desde otro Objeto usando nombres de Propiedad:

public static void Assign(this object destination, object source) { if (destination is IEnumerable && source is IEnumerable) { var dest_enumerator = (destination as IEnumerable).GetEnumerator(); var src_enumerator = (source as IEnumerable).GetEnumerator(); while (dest_enumerator.MoveNext() && src_enumerator.MoveNext()) dest_enumerator.Current.Assign(src_enumerator.Current); } else { var destProperties = destination.GetType().GetProperties(); foreach (var sourceProperty in source.GetType().GetProperties()) { foreach (var destProperty in destProperties) { if (destProperty.Name == sourceProperty.Name && destProperty.PropertyType.IsAssignableFrom(sourceProperty.PropertyType)) { destProperty.SetValue(destination, sourceProperty.GetValue(source, new object[] { }), new object[] { }); break; } } } }


Puedo establecer la propiedad de clase utilizando la reflexión donde mis propiedades de clase son solo una cadena. Ahora tengo que introducir un diccionario como miembro de esa clase pero no puedo establecer el valor. Estoy usando el siguiente fragmento de código para las propiedades de cadena.

object objval; objval=System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(className); objval.GetType().GetProperty(classpropertyname).SetValue(objval,Value);

Cómo establecer el valor del diccionario utilizando la reflexión


Reflexión, básicamente, es decir.

myObject.GetType().GetProperty(property).SetValue(myObject, "Bob", null);

o hay bibliotecas que ayudan tanto en términos de conveniencia como de rendimiento; por ejemplo con FastMember :

var wrapped = ObjectAccessor.Create(obj); wrapped[property] = "Bob";

(lo que también tiene la ventaja de no necesitar saber de antemano si se trata de un campo frente a una propiedad)


Sí, puedes usar Type.InvokeMember() :

using System.Reflection; MyObject obj = new MyObject(); obj.GetType().InvokeMember("Name", BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty, Type.DefaultBinder, obj, "Value");

Esto generará una excepción si obj no tiene una propiedad llamada Name o no se puede establecer.

Otro enfoque es obtener los metadatos de la propiedad y luego establecerlos. Esto le permitirá verificar la existencia de la propiedad y verificar que se pueda configurar:

using System.Reflection; MyObject obj = new MyObject(); PropertyInfo prop = obj.GetType().GetProperty("Name", BindingFlags.Public | BindingFlags.Instance); if(null != prop && prop.CanWrite) { prop.SetValue(obj, "Value", null); }


Sí, usando System.Reflection :

using System.Reflection; ... string prop = "name"; PropertyInfo pi = myObject.GetType().GetProperty(prop); pi.SetValue(myObject, "Bob", null);


También puede acceder a los campos de manera similar:

var obj=new MyObject(); FieldInfo fi = obj.GetType(). GetField("Name", BindingFlags.NonPublic | BindingFlags.Instance); fi.SetValue(obj,value)

Con la reflexión, todo puede ser un libro abierto :) En mi ejemplo, estamos vinculando a un campo de nivel de instancia privada.


También puedes hacer:

Type type = target.GetType(); PropertyInfo prop = type.GetProperty("propertyName"); prop.SetValue (target, propertyValue, null);

donde target es el objeto que tendrá su propiedad establecida.


Use algo como esto:

public static class PropertyExtension{ public static void SetPropertyValue(this object p_object, string p_propertyName, object value) { PropertyInfo property = p_object.GetType().GetProperty(p_propertyName); property.SetValue(p_object, Convert.ChangeType(value, property.PropertyType), null); } }

o

public static class PropertyExtension{ public static void SetPropertyValue(this object p_object, string p_propertyName, object value) { PropertyInfo property = p_object.GetType().GetProperty(p_propertyName); Type t = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType; object safeValue = (value == null) ? null : Convert.ChangeType(value, t); property.SetValue(p_object, safeValue, null); } }