2010-08-10 11 views
12

Per copiare i valori delle proprietà da un oggetto all'altro, di solito ottenere con seguente sintassi:Copiare i valori delle proprietà di un altro oggetto con C#

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

dove ca e CB sono della stessa classe.

Esiste uno strumento più semplice synatx o il metodo di utilità per aiutarci a ottenere lo stesso effetto?

Grazie.

+0

Questo è quello che stai cercando: [oggetti clonazione in C#] (https://stackoverflow.com/questions/ 78536/cloning-objects-in-c) –

risposta

3

non proprio. c'è un MemberwiseClone() ma che copia i riferimenti direttamente significa che si otterrebbe un riferimento allo stesso oggetto e che può essere cattivo. È possibile implementare l'interfaccia ICloneable e utilizzarla per una copia profonda. Preferisco creare il mio metodo Clone() perché l'interfaccia ICloneable restituisce un oggetto che deve essere lanciato.

+3

Non mi preoccuperei di ICloneable, è impossibile implementarlo correttamente perché l'interfaccia non consente al chiamante di indicare cosa intende per "clone". –

+0

credo che lo standard di fatto sia un clone profondo, ma ciò vale anche per ciò che ho detto sul metodo di clonazione, per una migliore sicurezza del tipo, ecc. –

10

Questa è una funzione utilizzata per copiare membri tra i modelli in ASP.NET MVC. Mentre si cerca un codice che funzioni per lo stesso tipo, questo codice supporterà anche altri tipi che hanno le stesse proprietà.

Utilizza i riflessi, ma in modo più pulito. Attenzione allo Convert.ChangeType: potresti non averne bisogno; potresti fare un controllo sul tipo invece di convertirlo.

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

Poiché si tratta di un metodo di estensione, l'utilizzo è semplice:

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

PropertyDescriptor.SetValue non ha funzionato per me, ha dovuto usare var convertProperties = typeof (TConvert) .GetProperties(); - che ti dà un elenco di PropertyInfo invece di PropertyDescriptor – MHolzmayr

+0

In Hindsight: "non ha funzionato", il codice è stato eseguito, ma non ha impostato alcun valore, ad esempio le proprietà bool, b/c avevano setter privati ​​(D ') Oh!). – 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

Se non mi sbaglio con quanto richiesto, il modo per raggiungere facilmente il valore copia proprietà tra due le istanze esistenti (anche se non dello stesso tipo) utilizzano Automapper.

  1. creare configurazione della mappatura
  2. e quindi chiamare .map (Soure, bersaglio)

Finché si mantiene immobile nel medesimo tipo e stessa convenzione di denominazione, tutto dovrebbe funzionare.

Esempio:

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

utilizzo:

promosion = YourClass.Convert<Promosion, PromosionExtension>(existsPromosion); 
Problemi correlati