Copy the property values to another object with C# [duplicate]
To copy the property values from one object to another, we usually achieve with following syntax:
ca.pro1 = cb.pro2;
ca.pro2 = cb.pro2;
where ca and cb are of the same class.
Is there any simpler synatx or utility method to help us to achieve the same effect?
Thank you.
public static void CopyPropertiesTo<T, TU>(this T source, TU dest)
{
var sourceProps = typeof (T).GetProperties().Where(x => x.CanRead).ToList();
var destProps = typeof(TU).GetProperties()
.Where(x => x.CanWrite)
.ToList();
foreach (var sourceProp in sourceProps)
{
if (destProps.Any(x => x.Name == sourceProp.Name))
{
var p = destProps.First(x => x.Name == sourceProp.Name);
if(p.CanWrite) { // check if the property can be set or no.
p.SetValue(dest, sourceProp.GetValue(source, null), null);
}
}
}
}
If I am not mistaken with what is required, the way to easily achieve property value copy between two existing instances (even not of the same type) is to use Automapper.
- create mapping configuration
- and then call .Map(soure, target)
As long as you keep property in same type and in same naming convention, all should work.
Example:
MapperConfiguration _configuration = new MapperConfiguration(cnf =>
{
cnf.CreateMap<SourceType, TargetType>();
});
var mapper = new Mapper(_configuration);
maper.DefaultContext.Mapper.Map(source, target)
This is a function that I used to copy members between models in ASP.NET MVC. While you seek a code that work for the same type, this code will also support other types that has the same properties.
It uses reflections, but in a more clean manner. Beware of the Convert.ChangeType
: you might not need it; you could do a check on the type instead of converting.
public static TConvert ConvertTo<TConvert>(this object entity) where TConvert : new()
{
var convertProperties = TypeDescriptor.GetProperties(typeof(TConvert)).Cast<PropertyDescriptor>();
var entityProperties = TypeDescriptor.GetProperties(entity).Cast<PropertyDescriptor>();
var convert = new TConvert();
foreach (var entityProperty in entityProperties)
{
var property = entityProperty;
var convertProperty = convertProperties.FirstOrDefault(prop => prop.Name == property.Name);
if (convertProperty != null)
{
convertProperty.SetValue(convert, Convert.ChangeType(entityProperty.GetValue(entity), convertProperty.PropertyType));
}
}
return convert;
}
Since this is an extension method, the usage is simple:
var result = original.ConvertTo<SomeOtherType>();
not really. there is a MemberwiseClone() but that copies references directly meaning you would get a reference to the same object and that can be bad. You can implement the ICloneable interface and use that for a deep copy. I prefer making my own Clone() method though because the ICloneable interface returns an Object that needs to be cast.
public static TTarget Convert<TSource, TTarget>(TSource sourceItem)
{
if (null == sourceItem)
{
return default(TTarget);
}
var deserializeSettings = new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace, };
var serializedObject = JsonConvert.SerializeObject(sourceItem, deserializeSettings);
return JsonConvert.DeserializeObject<TTarget>(serializedObject);
}
usage:
promosion = YourClass.Convert<Promosion, PromosionExtension>(existsPromosion);
精彩评论