2010-08-10 3 views
12

Um die Eigenschaftswerte von einem Objekt auf einen anderen zu kopieren, wir in der Regel mit folgenden Syntax erreichen:Kopieren Sie die Eigenschaftswerte auf ein anderes Objekt mit C#

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

wo ca und cb der gleichen Klasse ist.

Gibt es eine einfachere Synatx oder Hilfsmethode, die uns hilft, den gleichen Effekt zu erzielen?

Vielen Dank.

+0

Dies ist, was Sie suchen: [Cloning Objekte in C#] (https://stackoverflow.com/questions/ 78536/cloning-objects-in-c) –

Antwort

3

nicht wirklich. Es gibt eine MemberwiseClone(), die aber Verweise direkt kopiert, was bedeutet, dass Sie eine Referenz auf das gleiche Objekt bekommen und das kann schlecht sein. Sie können die Schnittstelle ICloneable implementieren und diese für eine tiefe Kopie verwenden. Ich bevorzuge es jedoch, meine eigene Clone() -Methode zu erstellen, weil die ICloneable-Schnittstelle ein Objekt zurückgibt, das umgewandelt werden muss.

+3

Ich würde mich nicht mit ICloneable beschäftigen, es ist unmöglich, es richtig zu implementieren, weil die Schnittstelle es dem Anrufer nicht erlaubt zu zeigen, was er mit "klonen" meint. –

+0

Ich glaube, dass der De-facto-Standard ein tiefer Klon ist, aber das geht auch mit dem, was ich über Ihre eigene Klon-Methode, für bessere Typ Sicherheit, etc. –

10

Dies ist eine Funktion, die ich verwendete, um Mitglieder zwischen Modellen in ASP.NET MVC zu kopieren. Während Sie einen Code suchen, der für denselben Typ funktioniert, unterstützt dieser Code auch andere Typen mit denselben Eigenschaften.

Es verwendet Reflexionen, aber in einer saubereren Art und Weise. Vorsicht vor der Convert.ChangeType: Sie könnten es nicht brauchen; Sie können den Typ überprüfen, anstatt ihn zu konvertieren.

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

Da dies eine Erweiterung Methode ist, ist die Verwendung einfach:

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

PropertyDescriptor.SetValue hat nicht funktioniert, musste var convertProperties verwenden = typeof (TConvert) .GetProperties(); - Das gibt Ihnen eine Liste von PropertyInfo anstelle von – MHolzmayr

+0

von PropertyDescriptor Im Nachhinein: "hat nicht funktioniert" bedeutet, der Code lief, aber es hat keine Werte, zum Beispiel bool Eigenschaften, b/c sie hatten private Setter (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

Wenn ich mit nicht täuschte, was erforderlich ist, die Art und Weise leicht Eigenschaftswert Kopie zwischen zwei zu erreichen vorhandene Instanzen (auch nicht vom selben Typ) ist zu verwenden.

  1. erstellen Mapping-Konfiguration
  2. und rufen Sie dann .MAP (soure, Ziel)

Solange Sie Eigentum in derselben Art halten und in gleicher Namenskonvention, die alle funktionieren sollen.

Beispiel:

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

Nutzung:

promosion = YourClass.Convert<Promosion, PromosionExtension>(existsPromosion); 
Verwandte Themen