Saltar al contenido

Copia de propiedad entre dos objetos usando la reflexión

Necesitamos una forma de «marcar» las propiedades que queremos que se copien del objeto padre. La mejor manera de hacerlo sería usando atributos para marcar estas propiedades.

Los atributos pueden definirse como metadatos. Pueden ser asignados a clases, propiedades, métodos, etc. Proporcionan metadatos sobre el objeto en el que se establecen. Por ejemplo, podemos definir la longitud máxima de una propiedad de cadena. Cuando establecemos una cadena en la propiedad, primero se comparará con los metadatos que proporcionamos previamente y la establecerá con el nuevo valor o no dependiendo de la longitud del nuevo valor de la cadena.

Copia de propiedad entre dos objetos usando la reflexión
Copia de propiedad entre dos objetos usando la reflexión

En nuestro caso, usaremos atributos para definir el nombre de la propiedad matriz. Le diremos al código que esta propiedad de subclase obtendrá su valor de la propiedad en la instancia padre.

En primer lugar necesitamos crear una clase para definir nuestro atributo. Será una clase simple que se deriva de la clase Atributo. Tendrá un único campo público que define el nombre de la propiedad correspondiente en el objeto padre. Aquí está el código para nuestro atributo:

123456789[AttributeUsage(AttributeTargets.Property)]publicclassMatchParentAttribute:Attribute{publicreadonlystring ParentPropertyName;publicMatchParentAttribute(string parentPropertyName){ ParentPropertyName = parentPropertyName;}}

csharp

Con nuestro atributo definido, podemos añadir a nuestra clase los atributos necesarios que teníamos antes:

1234567publicclassPersonMatch{[MatchParent("Nombre")]publicstring NameMatch {get;set;}[MatchParent("Apellido")]publicstring LastnameMatch {get;set;}}

csharp

Todo lo que tenemos que hacer ahora es comprobar el valor de los atributos de cada propiedad en el objeto hijo y encontrar el nombre correspondiente en el objeto padre:

123456789101112131415161718192021222324252627282930313233343536373839404142publicclassPropertyMatcher<TParent, TChild GetProperties();foreach(var hijoPropiedad en hijoPropiedades){var atributosParaPropiedad = hijoPropiedad.GetCustomAttributes(typeof(MatchParentAttribute),true);var isOfTypeMatchParentAttribute =false;MatchParentAttribute currentAttribute =null;foreach(var atributo en atributosParaPropiedad){if(atributo. GetType()==typeof(MatchParentAttribute)){ isOfTypeMatchParentAttribute =true; currentAttribute =(MatchParentAttribute) attribute;break;}}if(isOfTypeMatchParentAttribute){var parentProperties = parent. GetType().GetProperties();object parentPropertyValue =null;foreach(var parentProperty in parentProperties){if(parentProperty. Name == currentAttribute.ParentPropertyName){if(parentProperty.PropertyType== childProperty.PropertyType){ parentPropertyValue = parentProperty.GetValue(parent);}}} childProperty.SetValue(child, parentPropertyValue);}}}

csharp

Probemos nuestro código y veamos qué obtenemos:

123456789101112131415var usuario =newUser(){ Nombre de usuario ="murat", Dirección ="Alguna cadena de dirección aquí", Nombre ="murat", Apellido ="aykanat"};var personMatch =newPersonMatch();PropertyMatcher<Usuario, PersonMatch GenerateMatchedObject(user, personMatch);Console.WriteLine("Person:");Console.WriteLine(personMatch.NameMatch);Console.WriteLine(personMatch.LastnameMatch);

csharp

La salida será:

123Persona:murataykanat