2012-01-23 27 views
10

假設你有2類,像這樣:.NET/C#中是否有任何內容在對象之間複製值?

public class ClassA { 
    public int X { get; set; } 
    public int Y { get; set; } 
    public int Other { get; set; } 
} 

public class ClassB { 
    public int X { get; set; } 
    public int Y { get; set; } 
    public int Nope { get; set; } 
} 

現在想象你有每個類的一個實例,您想要將其值從複製到b中。有沒有像MemberwiseClone那樣複製屬性名稱匹配的值(當然也是容錯的 - 一個有get,另一個是集合等)?

var a = new ClassA(); var b = new classB(); 
a.CopyTo(b); // ?? 

像JavaScript這樣的語言非常容易。

我猜答案是否定的,但也許有一個簡單的選擇。我已經寫了一個反射庫來做到這一點,但是如果在較低的層次上嵌入到C#/ .NET中,可能會更有效率(以及爲什麼重新發明輪子)。

+2

看看AutoMapper:http://lostechies.com/jimmybogard/2009/01/23/automapper-the-object-object-mapper/ –

回答

10

在對象對象映射的框架中沒有任何東西,但有一個非常流行的庫,它是這樣做的:AutoMapper

AutoMapper是專爲解決一個看似 複雜的問題,一個簡單的小庫 - 擺脫的那個映射一個對象 另一個代碼。這種類型的代碼是相當沉悶和無聊的,所以 爲什麼不發明一個工具來爲我們做呢?

順便說一句,只是爲了學習,這裏是你可以實現你想要什麼簡單方式。我還沒有徹底測試它,它遠不作爲強大的/靈活/高性能爲AutoMapper,但希望有什麼東西走出的總體思路:

public void CopyTo(this object source, object target) 
{ 
    // Argument-checking here... 

    // Collect compatible properties and source values 
    var tuples = from sourceProperty in source.GetType().GetProperties() 
       join targetProperty in target.GetType().GetProperties() 
            on sourceProperty.Name 
            equals targetProperty.Name 

       // Exclude indexers 
       where !sourceProperty.GetIndexParameters().Any() 
        && !targetProperty.GetIndexParameters().Any() 

       // Must be able to read from source and write to target. 
       where sourceProperty.CanRead && targetProperty.CanWrite 

       // Property types must be compatible. 
       where targetProperty.PropertyType 
            .IsAssignableFrom(sourceProperty.PropertyType) 

       select new 
       { 
        Value = sourceProperty.GetValue(source, null), 
        Property = targetProperty 
       }; 

    // Copy values over to target. 
    foreach (var valuePropertyTuple in tuples) 
    { 
     valuePropertyTuple.Property 
          .SetValue(target, valuePropertyTuple.Value, null); 

    } 
} 
-1

據我知道這不存在。我一直在做它的方式是:

public static T DeepCopy(T oldclass) 
{ 
    using (MemoryStream stream = new MemoryStream()) 
    { 
     BinaryFormatter formatter = new BinaryFormatter(); 
     formatter.Serialize(stream, oldclass); 
     ms.Position = 0; 
     return (T)formatter.Deserialize(stream); 
    } 
} 
1

有這樣的事在.NET中,我所知道的,但一個庫,能夠做到這一點(和更多)是AutoMapper。對於你的情況,是這樣的:

_mapper.Map<A, B> (a, b); 
-1

看到界面System.ICloneable和方法System.Object.MemberwiseClone()。正如在MSDN文檔指出,

MemberwiseClone方法通過創建一個新對象,然後複製當前對象的非靜態字段到新對象創建一個淺拷貝。如果某個字段是值類型,則會執行該字段的逐位副本。如果一個字段是一個引用類型,則引用被複制,但引用的對象不是;因此,原始對象及其克隆涉及同一個對象。
+0

所以你說這會工作? 'classB = classA.MemberwiseClone()as classB' –

相關問題