Gilūs klonų objektai

Noriu padaryti kažką panašaus:

 MyObject myObj = GetMyObj(); // Create and fill a new object MyObject newObj = myObj.Clone(); 

Ir tada pakeiskite naują objektą, kuris neatspindi pradinio objekto.

Man dažnai nereikia šios funkcijos, taigi, kai tai buvo būtina, pasinaudojau nauju objektu, o po to nukopijuoju kiekvieną turtą atskirai, bet visada palieku jausmą, kad yra geresnis ar elegantiškesnis būdas susidoroti su situacija.

Kaip aš galiu klonuoti arba giliai nukopijuoti objektą taip, kad klonuotas objektas galėtų būti pakeistas be jokių pakeitimų, atspindinčių pradinį objektą?

1844 m
17 сент. nustatė Jordan Arron 17 sept. 2008-09-17 03:06 '08 at 3:06 2008-09-17 03:06
@ 39 atsakymų
  • 1
  • 2

Nors standartinė praktika yra įdiegti „ ICloneable sąsają (aprašytą čia , taigi aš negaliu ICloneable ), čia yra geras klonas klonuotiems klonams, kuriuos kurį laiką ICloneable Kodekso projekte ir įtraukė jį į mūsų daiktus.

Kaip minėta kituose skyriuose, tai reikalauja, kad jūsų objektai būtų serializuojami.

 using System; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; /// <summary> /// Reference Article http://www.codeproject.com/KB/tips/SerializedObjectCloner.aspx /// Provides a method for performing a deep copy of an object. /// Binary Serialization is used to perform the copy. /// </summary> public static class ObjectCopier { /// <summary> /// Perform a deep Copy of the object. /// </summary> /// <typeparam name="T">The type of object being copied.</typeparam> /// <param name="source">The object instance to copy.</param> /// <returns>The copied object.</returns> public static T Clone<T>(T source) { if (!typeof(T).IsSerializable) { throw new ArgumentException("The type must be serializable.", "source"); } // Don't serialize a null object, simply return the default for that object if (Object.ReferenceEquals(source, null)) { return default(T); } IFormatter formatter = new BinaryFormatter(); Stream stream = new MemoryStream(); using (stream) { formatter.Serialize(stream, source); stream.Seek(0, SeekOrigin.Begin); return (T)formatter.Deserialize(stream); } } } 

Idėja yra tai, kad jis serializuoja jūsų objektą ir po to deserializuoja jį į naują objektą. Privalumas yra tas, kad jums nereikės nerimauti visko klonuojant, kai objektas tampa pernelyg sudėtingas.

Ir naudojant išplėtimo metodus (taip pat iš pradinio šaltinio):

Jei norite naudoti naują C # 3.0 plėtinio metodą, pakeiskite metodą į šį parašą:

 public static T Clone<T>(this T source) { //... } 

Dabar metodas skambina tiesiog tampa objectBeingCloned.Clone(); .

EDIT (2015 m. Sausio 10 d.) Maniau, kad pasikeitė mano mintis, pažymėdamas, kad neseniai pradėjau naudoti „Newtonsoft“ Jsoną, turėčiau būti lengviau ir išvengti „Serializable“ žymių pridėtinės vertės. ( Pastaba, kad privatūs nariai nėra klonuojami naudojant JSON metodą)

 /// <summary> /// Perform a deep Copy of the object, using Json as a serialisation method. NOTE: Private members are not cloned using this method. /// </summary> /// <typeparam name="T">The type of object being copied.</typeparam> /// <param name="source">The object instance to copy.</param> /// <returns>The copied object.</returns> public static T CloneJson<T>(this T source) { // Don't serialize a null object, simply return the default for that object if (Object.ReferenceEquals(source, null)) { return default(T); } // initialize inner objects individually // for example in default constructor some list property initialized with some values, // but in 'source' these items are cleaned - // without ObjectCreationHandling.Replace default constructor values will be added to result var deserializeSettings = new JsonSerializerSettings {ObjectCreationHandling = ObjectCreationHandling.Replace}; return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source), deserializeSettings); } 
1479
17 сент. johnc atsakymas 17 sep . 2008-09-17 03:18 '08 at 3:18 2008-09-17 03:18

Man reikia labai paprastų objektų, daugiausia primityvių ir sąrašų, klonerio. Jei jūsų objektas yra nesuderinamas su serijiniu JSON, šis metodas bus triksas. Tam nereikia keisti ar įgyvendinti sąsajų klonuotoje klasėje, tik JSON serializatoriumi, pvz., JSON.NET.

border=0
 public static T Clone<T>(T source) { var serialized = JsonConvert.SerializeObject(source); return JsonConvert.DeserializeObject<T>(serialized); } 
185
03 апр. atsakymas craastad 03 Bal. 2013-04-03 16:31 '13, 16:31, 2013-04-03 16:31

Priežastis, kodėl nenaudojama ICloneable, yra ne todėl, kad ji neturi bendros sąsajos. Priežastis yra ne naudoti, nes ji yra neaiški . Jame nėra aišku, ar gaunate seklią ar gilią kopiją; kas yra menininkas.

Taip, „ MemberwiseClone daro seklią kopiją, tačiau „ MemberwiseClone “ priešingai nei Clone ; tai galbūt būtų DeepClone , kuris neegzistuoja. Kai naudojate objektą per „ICloneable“ sąsają, negalite žinoti, kokio tipo pagrindinio objekto klonavimas atliekamas. (Ir XML komentarai nenurodo, nes gausite komentarus apie sąsają, o ne su objekto klonavimo metodu susijusius komentarus.)

Paprastai atlieku tik Copy metodą, kuris daro būtent tai, ko noriu.

149
17 сент. atsakymą pateikė Ryan Lundy 17 sep. 2008-09-17 04:12 '08 at 4:12 2008-09-17 04:12

Perskaičius daugybę čia susijusių variantų ir galimų šios problemos sprendimo būdų, manau, kad visos galimybės yra labai gerai apibendrintos Ian P sąsajoje (visos kitos parinktys yra parinktys), o geriausias sprendimas pateikiamas Pedro77 nuorodoje į komentarus.

Taigi čia tiesiog nukopijuoju atitinkamas šių dviejų nuorodų dalis. Taigi, galime:

Geriausias dalykas, kurį galite padaryti, kad klonuotų objektus c aštriai!

Visų pirma, tai visi mūsų variantai:

Greita giliai kopijavimas, naudojant ekspresijos medžius, taip pat lygina klonavimo efektyvumą naudojant serializaciją, atspindžius ir išraišką.

Kodėl aš renkuosi ICloneable (t. Y. Rankiniu būdu)

Venkat Subramaniam (čia pateikiamas atleidimas iš darbo) išsamiai paaiškina, kodėl .

Visi jo apskritimo straipsniai aplink pavyzdį, kuris bando taikyti daugeliu atvejų, naudoja 3 objektus: asmenį, smegenis ir miestą. Mes norime klonuoti asmenį, kuris turės savo smegenis, bet tą patį miestą. Galite peržiūrėti visas problemas, kurias bet kuris iš pirmiau minėtų metodų gali sukelti arba skaityti straipsnį.

Tai mano šiek tiek pakeista jo produkcijos versija:

Objekto kopijavimas, nurodant New po kurio seka klasės pavadinimas, dažnai sukelia kodo išplėtimą. Naudojant kloną, prototipo šablono naudojimas yra geriausias būdas tai pasiekti. Tačiau, naudojant kloną, kaip numatyta C # (ir Java), gali būti gana problemiškas. Geriau pateikti saugomą (ne viešą) kopijavimo konstruktorių ir jį vadinti iš klonavimo metodo. Tai leidžia mums perduoti objekto sukūrimo užduotį į pačios klasės egzempliorių, tokiu būdu užtikrinant išplėtimą ir saugų objektų kūrimą naudojant saugomą kopijavimo konstruktorių.

Tikimės, kad šis įgyvendinimas gali paaiškinti situaciją:

 public class Person : ICloneable { private final Brain brain; // brain is final since I do not want // any transplant on it once created! private int age; public Person(Brain aBrain, int theAge) { brain = aBrain; age = theAge; } protected Person(Person another) { Brain refBrain = null; try { refBrain = (Brain) another.brain.clone(); // You can set the brain in the constructor } catch(CloneNotSupportedException e) {} brain = refBrain; age = another.age; } public String toString() { return "This is person with " + brain; // Not meant to sound rude as it reads! } public Object clone() { return new Person(this); } … } 

Dabar apsvarstykite, ką klasė gauna iš Asmens.

 public class SkilledPerson extends Person { private String theSkills; public SkilledPerson(Brain aBrain, int theAge, String skills) { super(aBrain, theAge); theSkills = skills; } protected SkilledPerson(SkilledPerson another) { super(another); theSkills = another.theSkills; } public Object clone() { return new SkilledPerson(this); } public String toString() { return "SkilledPerson: " + super.toString(); } } 

Galite pabandyti paleisti šį kodą:

 public class User { public static void play(Person p) { Person another = (Person) p.clone(); System.out.println(p); System.out.println(another); } public static void main(String[] args) { Person sam = new Person(new Brain(), 1); play(sam); SkilledPerson bob = new SkilledPerson(new SmarterBrain(), 1, "Writer"); play(bob); } } 

Rezultatai bus:

 This is person with Brain@1fcc69 This is person with Brain@253498 SkilledPerson: This is person with SmarterBrain@1fef6f SkilledPerson: This is person with SmarterBrain@209f4e 

Atkreipkite dėmesį, kad jei išsaugosime objektų skaičiaus skaičių, čia įdiegtas klonas bus teisingas objektų skaičiaus skaičius.

84
26 сент. Atsakymas pateikiamas cregox 26 sep . 2012-09-26 23:18 '12 at 23:18 2012-09-26 23:18

Man labiau patinka klonų kopijavimo dizaineris. Tikslas yra aiškus.

68
17 сент. Atsakymas pateikiamas Nick 17 Sep. 2008-09-17 03:13 '08 at 3:13 2008-09-17 03:13

Paprastas visų viešųjų savybių kopijavimo metodas. Veikia bet kuriam objektui ir nereikalauja, kad klasė būtų [Serializable] . Galima išplėsti į kitą prieigos lygį.

 public static void CopyTo( this object S, object T ) { foreach( var pS in S.GetType().GetProperties() ) { foreach( var pT in T.GetType().GetProperties() ) { if( pT.Name != pS.Name ) continue; ( pT.GetSetMethod() ).Invoke( T, new object[] { pS.GetGetMethod().Invoke( S, null ) } ); } }; } 
36
16 марта '11 в 14:38 2011-03-16 14:38 atsakymą pateikė Konstantinas Salavatovas kovo 16 d., 14:38, 2011-03-16 14:38

Na, turėjau problemų naudojant „ICloneable“ „Silverlight“, bet man patiko seralizacijos idėja, galiu seralizuoti XML, todėl aš tai padariau:

 static public class SerializeHelper { //Michael White, Holly Springs Consulting, 2009 //michael@hollyspringsconsulting.com public static T DeserializeXML<T>(string xmlData) where T:new() { if (string.IsNullOrEmpty(xmlData)) return default(T); TextReader tr = new StringReader(xmlData); T DocItms = new T(); XmlSerializer xms = new XmlSerializer(DocItms.GetType()); DocItms = (T)xms.Deserialize(tr); return DocItms == null ? default(T) : DocItms; } public static string SeralizeObjectToXML<T>(T xmlObject) { StringBuilder sbTR = new StringBuilder(); XmlSerializer xmsTR = new XmlSerializer(xmlObject.GetType()); XmlWriterSettings xwsTR = new XmlWriterSettings(); XmlWriter xmwTR = XmlWriter.Create(sbTR, xwsTR); xmsTR.Serialize(xmwTR,xmlObject); return sbTR.ToString(); } public static T CloneObject<T>(T objClone) where T:new() { string GetString = SerializeHelper.SeralizeObjectToXML<T>(objClone); return SerializeHelper.DeserializeXML<T>(GetString); } } 
28
02 дек. Atsakymą pateikė Michael White gruodžio 2 d. 2009-12-02 20:39 '09 at 20:39 2009-12-02 20:39

Jei jau naudojate trečiosios šalies programą, pvz., „ ValueInjecter“ arba „ Automapper“ , galite tai padaryti:

 MyObject oldObj; // The existing object to clone MyObject newObj = new MyObject(); newObj.InjectFrom(oldObj); // Using ValueInjecter syntax 

Naudodami šį metodą, nereikia įdiegti ISerializable arba IClonable savo objektuose. Tai būdinga MVC / MVVM modeliui, todėl sukurtos tokios paprastos priemonės.

žr. sprendimą dėl gilaus injektoriaus vertės klonavimo „CodePlex“ .

26
15 окт. Michael Cox atsakymas spalio 15 d 2012-10-15 20:55 '12 8:55 val. 2012-10-15 20:55

Aš ką tik sukūriau projektą „ CloneExtensions . Jis atlieka greitą, gilų kloną, naudodamas paprastas priskyrimo operacijas, sukurtas išraiškos runtime kodą.

Kaip jį naudoti?

Užuot rašę savo Clone arba Copy metodus su priskyrimo tonu tarp laukų ir savybių, sukurkite programą sau naudodami išraiškos medį. GetClone<T>() metodas, pažymėtas kaip pratęsimo metodas, leidžia jį skambinti jūsų instancijoje:

 var newInstance = source.GetClone(); 

Galite pasirinkti, ką reikia nukopijuoti iš source į newInstance naudodami „ CloningFlags enum“:

 var newInstance = source.GetClone(CloningFlags.Properties | CloningFlags.CollectionItems); 

Ką galima klonuoti?

  • Primityvus (int, uint, baitas, dvigubas, char ir tt), žinomi nepakeičiami tipai (DateTime, TimeSpan, String) ir delegatai (įskaitant Action, Func ir kt.)
  • Negalima
  • T [] masyvai
  • Individualios klasės ir struktūros, įskaitant bendras klases ir struktūras.

Klasės nariai / struktūros klonuojami:

  • Viešųjų, o ne tekstinių laukų reikšmės
  • Viešosios nuosavybės vertės, naudojant tiek „get“, tiek „set“
  • ICollection diegimo tipų rinkimo elementai

Kaip greitai?

Sprendimas yra greitesnis nei atspindys, nes nario informacija turi būti renkama tik vieną kartą, kol „ GetClone<T> pirmą kartą naudojamas tam tikram T tipui.

Jis taip pat yra greitesnis nei serializavimo sprendimas, kai klonuojate daugiau nei kelių tos pačios rūšies T

ir dar daugiau ...

Sužinokite daugiau apie sukurtas išraiškas dokumentuose .

Debug išraiškos iš List<int> :

 .Lambda #Lambda1<System.Func`4[System.Collections.Generic.List`1[System.Int32],CloneExtensions.CloningFlags,System.Collections.Generic.IDictionary`2[System.Type,System.Func`2[System.Object,System.Object]],System.Collections.Generic.List`1[System.Int32]]>( System.Collections.Generic.List`1[System.Int32] $source, CloneExtensions.CloningFlags $flags, System.Collections.Generic.IDictionary`2[System.Type,System.Func`2[System.Object,System.Object]] $initializers) { .Block(System.Collections.Generic.List`1[System.Int32] $target) { .If ($source == null) { .Return #Label1 { null } } .Else { .Default(System.Void) }; .If ( .Call $initializers.ContainsKey(.Constant<System.Type>(System.Collections.Generic.List`1[System.Int32])) ) { $target = (System.Collections.Generic.List`1[System.Int32]).Call ($initializers.Item[.Constant<System.Type>(System.Collections.Generic.List`1[System.Int32])] ).Invoke((System.Object)$source) } .Else { $target = .New System.Collections.Generic.List`1[System.Int32]() }; .If ( ((System.Byte)$flags  (System.Byte).Constant<CloneExtensions.CloningFlags>(Fields)) == (System.Byte).Constant<CloneExtensions.CloningFlags>(Fields) ) { .Default(System.Void) } .Else { .Default(System.Void) }; .If ( ((System.Byte)$flags  (System.Byte).Constant<CloneExtensions.CloningFlags>(Properties)) == (System.Byte).Constant<CloneExtensions.CloningFlags>(Properties) ) { .Block() { $target.Capacity = .Call CloneExtensions.CloneFactory.GetClone( $source.Capacity, $flags, $initializers) } } .Else { .Default(System.Void) }; .If ( ((System.Byte)$flags  (System.Byte).Constant<CloneExtensions.CloningFlags>(CollectionItems)) == (System.Byte).Constant<CloneExtensions.CloningFlags>(CollectionItems) ) { .Block( System.Collections.Generic.IEnumerator`1[System.Int32] $var1, System.Collections.Generic.ICollection`1[System.Int32] $var2) { $var1 = (System.Collections.Generic.IEnumerator`1[System.Int32]).Call $source.GetEnumerator(); $var2 = (System.Collections.Generic.ICollection`1[System.Int32])$target; .Loop { .If (.Call $var1.MoveNext() != False) { .Call $var2.Add(.Call CloneExtensions.CloneFactory.GetClone( $var1.Current, $flags, $initializers)) } .Else { .Break #Label2 { } } } .LabelTarget #Label2: } } .Else { .Default(System.Void) }; .Label $target .LabelTarget #Label1: } 

}

kuri turi tokią pačią reikšmę kaip ir šis C # kodas:

 (source, flags, initializers) => { if(source == null) return null; if(initializers.ContainsKey(typeof(List<int>)) target = (List<int>)initializers[typeof(List<int>)].Invoke((object)source); else target = new List<int>(); if((flags  CloningFlags.Properties) == CloningFlags.Properties) { target.Capacity = target.Capacity.GetClone(flags, initializers); } if((flags  CloningFlags.CollectionItems) == CloningFlags.CollectionItems) { var targetCollection = (ICollection<int>)target; foreach(var item in (ICollection<int>)source) { targetCollection.Add(item.Clone(flags, initializers)); } } return target; } 

Ar neatrodo, kad parašytumėte savo Clone metodą List<int> ?

25
25 дек. atsakymą pateikė MarcinJuraszek 25 d. 2013-12-25 01:56 '13 at 1:56 2013-12-25 01:56

Trumpas atsakymas yra: paveldi ICloneable sąsają ir tada įdiegti .clone funkciją. Klonas turi kopijuoti tvarką ir atlikti gilų kopiją bet kuriam nariui, kuris to reikalauja, ir tada grąžinti rezultato objektą. Tai yra rekursinė operacija (tai reikalauja, kad visi klasės nariai, kuriems norite klonuoti, yra arba vertybių tipai, arba įgyvendinti IClonable ir kad jų nariai yra arba vertybių tipai, arba įgyvendina ICloneable ir tt).

Šiame straipsnyje rasite išsamesnį paaiškinimą apie klonavimą naudojant ICloneable.

Ilgas atsakymas: „Tai priklauso.“ Kaip minėjo kiti, „ICloneable“ nepalaiko generiniai vaistai, reikalauja specialių aplinkybių, susijusių su apvaliomis nuorodomis į klases, ir kai kurie juos laiko „klaidomis“ .NET Framework. Serializavimo metodas priklauso nuo jūsų serializuojamų objektų, kurių jie negali būti, ir jūs negalite valdyti. Vis dar yra daug diskusijų visuomenėje, kurios yra „geriausia“ praktika. Iš tiesų, nė vienas iš sprendimų nėra vienas iš tinkamiausių visoms situacijoms, pavyzdžiui, ICloneable, iš pradžių aiškinamas kaip.

Žiūrėkite šį „ Corner Developer“ straipsnį dėl kelių papildomų parinkčių (kreditas „Ian“).

20
17 сент. Atsakymas pateikiamas Zach Burlingame 17 sep. 2008-09-17 03:14 '08 at 3:14 2008-09-17 03:14

Jei norite, kad tikras klonavimas būtų nežinomas, galite pažvelgti į spartų klonavimą .

Šis išraiška pagrįstas klonavimas veikia apie 10 kartų greičiau nei binarinė serializacija ir palaiko viso objekto vientisumą.

Tai reiškia: jei kelis kartus nurodysite tą patį objektą savo hierarchijoje, klonas taip pat turės vieną pavyzdį.

Nereikia jokių sąsajų, atributų ar bet kokio kito klonuotų objektų modifikavimo.

15
16 февр. Atsakymą pateikė Michael Sander , vasario 16 d. 2015-02-16 14:30 '15 - 14.30 val. 2015-02-16 14:30
  • Iš esmės, jums reikia įdiegti ICloneable sąsają ir tada įgyvendinti objekto struktūros kopijavimą.
  • Jei tai yra gili visų narių kopija, turite apdrausti (nesusiję su pasirinktu sprendimu), kad visi vaikai būtų klonuoti.
  • Kartais per šį procesą reikia žinoti tam tikrus apribojimus, pavyzdžiui, jei nukopijuojate ORM objektus, dauguma karkasų leidžia tik vienam objektui, prijungtam prie seanso, ir jūs NEGALITE gaminti šio objekto klonų arba, jei įmanoma, turėtumėte rūpintis šių objektų prijungimu. sesijos metu.

Sveikinimai.

15
17 сент. atsakymas, kurį davė dimarzionistas 17 sep . 2008-09-17 03:11 '08 at 3:11 am 2008-09-17 03:11

Geriausia įgyvendinti, pavyzdžiui, išplėtimo metodą

 public static T DeepClone<T>(this T originalObject) {  } 

tada naudokite jį bet kur

 var copy = anyObject.DeepClone(); 

Galime turėti tris įgyvendinimo būdus:

Visi susiję metodai veikia gerai ir buvo išbandyti.

15
04 авг. atsakymas duotas frakon 04 rug . 2016-08-04 01:24 '16 at 1:24 2016-08-04 01:24

Su tuo susidūriau, norėdamas įveikti „ .NET “ trūkumus, kad rankiniu būdu nukopijuotumėte „<T>“ sąrašą.

Naudoju tai:

 static public IEnumerable<SpotPlacement> CloneList(List<SpotPlacement> spotPlacements) { foreach (SpotPlacement sp in spotPlacements) { yield return (SpotPlacement)sp.Clone(); } } 

Ir kitoje vietoje:

 public object Clone() { OrderItem newOrderItem = new OrderItem(); ... newOrderItem._exactPlacements.AddRange(SpotPlacement.CloneList(_exactPlacements)); ... return newOrderItem; } 

Bandžiau galvoti apie tai, kas tai daro, bet tai neįmanoma, nes produkcija neveikia anoniminio metodo blokuose.

Dar geriau, naudokite bendrą sąrašą <t>:

 class Utility<T> where T : ICloneable { static public IEnumerable<T> CloneList(List<T> tl) { foreach (T t in tl) { yield return (T)t.Clone(); } } } 
10
30 сент. Atsakymas duotas Daniel Mošmondor rugsėjo 30 d 2009-09-30 12:51 '09, 12:51, 2009-09-30 12:51

Laikykite paprastus dalykus ir naudokite „ AutoMapper“ , kaip minėta kitose, tai yra paprasta nedidelė biblioteka, skirta vienam objektui suderinti su kita ... Jei norite kopijuoti objektą kitam su tuo pačiu tipu, viskas, ko jums reikia, yra trys kodo eilutės:

 MyType source = new MyType(); Mapper.CreateMap<MyType, MyType>(); MyType target = Mapper.Map<MyType, MyType>(source); 

Tikslinis objektas dabar yra šaltinio objekto kopija. Ar ne pakankamai lengva? Sukurkite išplėtimo būdą, kuris bus naudojamas visur jūsų sprendime:

 public static T Copy<T>(this T source) { T copy = default(T); Mapper.CreateMap<T, T>(); copy = Mapper.Map<T, T>(source); return copy; } 

Naudojant išplėtimo metodą, trys eilutės tampa viena eilute:

 MyType copy = source.Copy(); 
9
28 мая '16 в 14:02 2016-05-28 14:02 atsakymas pateikiamas sukrauti gegužės 28 d., 16 val. 14:02 2016-05-28 14:02

Čia pateikiamas gilus įgyvendinimas:

 public static object CloneObject(object opSource) { //grab the type and create a new instance of that type Type opSourceType = opSource.GetType(); object opTarget = CreateInstanceOfType(opSourceType); //grab the properties PropertyInfo[] opPropertyInfo = opSourceType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); //iterate over the properties and if it has a 'set' method assign it from the source TO the target foreach (PropertyInfo item in opPropertyInfo) { if (item.CanWrite) { //value types can simply be 'set' if (item.PropertyType.IsValueType || item.PropertyType.IsEnum || item.PropertyType.Equals(typeof(System.String))) { item.SetValue(opTarget, item.GetValue(opSource, null), null); } //object/complex types need to recursively call this method until the end of the tree is reached else { object opPropertyValue = item.GetValue(opSource, null); if (opPropertyValue == null) { item.SetValue(opTarget, null, null); } else { item.SetValue(opTarget, CloneObject(opPropertyValue), null); } } } } //return the new item return opTarget; } 
8
06 сент. atsakymas duotas dougajmcdonald 06 sep . 2011-09-06 10:38 '11, 10:38, 2011-09-06 10:38

Apskritai, jūs įgyvendinate ICloneable sąsają ir įdiegiate kloną patys. C # objektai turi integruotą „MemberwiseClone“ metodą, kuris atlieka seklią kopiją, kuri gali padėti atlikti visus primityvius.

Dėl gilios kopijos nėra jokio būdo žinoti, kaip tai padaryti automatiškai.

7
17 сент. atsakymas pateikiamas „ HappyDude“ 17 sep . 2008-09-17 03:09 '08 at 3:09 2008-09-17 03:09

Q. Kodėl turėčiau pasirinkti šį atsakymą?

  • Pasirinkite šį atsakymą, jei norite, kad maksimalus greitis būtų .NET.
  • Игнорируйте этот ответ, если вам нужен действительно простой способ клонирования.

Другими словами, пойти с другим ответом, если у вас нет узкого места производительности, которое требуется для исправления, и вы можете доказать это с помощью профайлера .

10 раз быстрее, чем другие методы