2010-08-10 17 views
12

ile başka bir nesneye özellik değerleri, genellikle aşağıdaki sözdizimi ile elde: ca ve cb aynı sınıfın olanKopya başka bir nesneden özellik değerlerini kopyalamak için C#

ca.pro1 = cb.pro2; 
ca.pro2 = cb.pro2; 

. Aynı efekti elde etmemize yardımcı olmak için daha basit bir eşzamanlılık veya yardımcı yöntem var mı?

Teşekkür ederiz.

+0

Bu aradığınız budur: ([C# Klonlama nesneler] https://stackoverflow.com/questions/ 78536/klonlama-c nesneleri-in-c) –

cevap

3

gerçekten değil. MemberwiseClone() var ama bu referansları doğrudan, aynı nesneye referans alacağınız ve kötü olabileceği anlamına gelir. ICloneable arayüzünü uygulayabilir ve bunu derin bir kopya için kullanabilirsiniz. Kendi Clone() yöntemimi yapmayı tercih ediyorum, çünkü ICONeable arabirimi, dönüştürülmesi gereken bir nesne döndürüyor. Bu, ASP.NET MVC'deki modeller arasında üyeleri kopyalamak için kullandığım bir işlevdir.

+3

ICONABLE ile uğraşmak istemem, bu arayüzün uygun şekilde uygulanması imkansız çünkü arayüz arayanın "klon" ile ne demek istediğini göstermesine izin vermiyor. –

+0

Ben de facto standart derin bir klon olduğuna inanıyorum, ama aynı zamanda daha iyi tip güvenlik, vb için kendi klon yöntemi yapma hakkında söylediğim ile gider –

10

Aynı tür için çalışan bir kod ararken, bu kod aynı özelliklere sahip diğer türleri de destekleyecektir.

Yansıma kullanır, ancak daha temiz bir şekilde. Convert.ChangeType'a dikkat edin: buna ihtiyacınız olmayabilir; Dönüştürme yerine tür üzerinde bir kontrol yapabilirsiniz. Bu bir uzantısı yöntemidir yana

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; 
} 

, kullanım basit:

var result = original.ConvertTo<SomeOtherType>(); 
+0

PropertyDescriptor.SetValue benim için işe yaramadı, var convertProperties kullanmak zorunda kaldı = typeof (TConvert) .GetProperties(); - size PropertyDescriptor'un – MHolzmayr

+0

yerine PropertyInfo listesi verir. Hindsight'da: "işe yaramadı" anlamında, kod koştu, ancak herhangi bir değer ayarlamamış, örneğin bool özellikleri, b/c özel dizileri vardı (D ' ah!). – MHolzmayr

14
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); 
      } 
     } 

    } 

} 
3

ben ne gereklidir ile yanlış değil, yolu kolayca ikisi arasında özellik değeri kopyasını elde etmek için (aynı türden değil) mevcut örnekleri Automapper kullanmak içindir.

  1. haritalama yapılandırma
  2. oluşturmak ve sonra

sürece aynı tip ve aynı adlandırma kuralı mülk tutmak gibi, bütün çalışması gerekir .map (Soure, hedef) diyoruz.

Örnek:

MapperConfiguration _configuration = new MapperConfiguration(cnf => 
      { 
       cnf.CreateMap<SourceType, TargetType>(); 
      }); 
var mapper = new Mapper(_configuration); 
maper.DefaultContext.Mapper.Map(source, target) 
1
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); 
     } 

kullanımı:

promosion = YourClass.Convert<Promosion, PromosionExtension>(existsPromosion); 
İlgili konular