שני הסנטים שלי בעותק עמוק לעומת עותק רדוד ברשת

Microsoft .Net מספקת תמיכה בשיבוט אובייקטים - יכולת ליצור עותק מדויק של אובייקט (המכונה גם שיבוט). שיבוט יכול להיות משני סוגים: העתק רדוד והעתקה עמוקה. בעוד שניתן ליישם את הראשון על ידי ביצוע שיחה לשיטת MemberwiseClone של מחלקת System.Object, יישום האחרון הוא קצת מסובך מכיוון שאין לך תמיכה בכך במסגרת כברירת מחדל. בעיקרו של דבר, בעוד שהעתק רדוד מעתיק את ההפניות מבטאים את האובייקטים המוזכרים, שיבוט עמוק יוצר עותק של אובייקט המקור יחד עם ההפניות שלו.

מהן כל האפשרויות הקיימות לשיבוט?

כדי לשכפל מופע של מחלקה ב- C #, יש לך כמה אפשרויות לבחירה. אלה כוללים את הדברים הבאים:

  • באמצעות שיטת System.Object.MemberwiseClone לביצוע עותק רדוד
  • שימוש בשיקוף באמצעות ניצול שיטת Activator.CreateInstance
  • שימוש בסידור
  • על ידי יישום הממשק IClonable

שים לב שכאשר משבטים אובייקטים או מופעים של מחלקות ב- .Net, אינך צריך לקחת בחשבון איברים סטטיים או שדות סטטיים. הסיבה היא שאובייקטים סטטיים מאוחסנים במיקום זיכרון משותף ולכם מוקצה זיכרון אחד לכל תחום יישום.

עותק רדוד לעומת עותק עמוק

שקול עובד שכיר וכי אנו יוצרים מופע של מחלקת העובדים כמוצג להלן.

Employee emp = new Employee();

Employee clone = emp;

עיין בקטע הקוד שלמעלה. מפעיל ההקצאה "=" יעתיק את ההפניה ולא את האובייקט בפועל. השיטה MemberwiseClone () המוגדרת במחלקה System.Object עושה בדיוק את אותו הדבר. אלה דוגמאות להעתקה רדודה. מכאן שכאשר אתה משתמש במפעיל הקצאה כדי להעתיק ולהתנגד לאחר או להשתמש בשיטת Memberwise.Clone (), אתה בעצם עושה עותק רדוד של האובייקט.

בעוד שבעותק רדוד חברי האובייקט המועתק מתייחסים לאותו אובייקט כמו האובייקט המקורי, בעותק עמוק נוצרים מופעים נפרדים של כל אחד מחברי סוג ההתייחסות במופע המקורי במופע החדש או המשובט. מכאן שאם יש לך סוג התייחסות במופע המקורי, המופע החדש יכיל גם את אותו חבר סוג התייחסות, אך סוג התייחסות זה יצביע על מופע חדש לגמרי.

בהעתקה רדודה נוצר אובייקט חדש ואז המועתקים החברים הלא סטטיים של אובייקט המקור לאובייקט היעד או לאובייקט החדש. אם האיבר הוא שדה מסוג ערך אז מבצעים עותק שדה אחר ביט של השדה. לעומת זאת, אם החבר המועתק הוא סוג התייחסות, ההפניה מועתקת. מכאן, איבר ההתייחסות בתוך האובייקט המקורי ואובייקטים היעד מתייחסים לאותו אובייקט בזיכרון.

אם יש לך אוסף עם אלמנטים בודדים ותרצה לבצע העתקה רדודה של מופע האוסף. יש לציין כי עותק רדוד של מופע אוסף מעתיק את מבנה האוסף אך לא את האלמנטים שבתוך האוסף. לפיכך, לאחר ביצוע עותק רדוד של מופע האוסף, יהיו לך שני אוספים המשתפים את האלמנטים הבודדים של האוסף. להפך, אם תבצע עותק עמוק של מופע האוסף, יהיו לך שני מופעי אוסף עם האלמנטים הבודדים של האוסף המקורי.

יישום עותק עמוק באמצעות סידור

אתה יכול ליישם עותק עמוק בדרכים רבות. אחת הדרכים המועדפות ביותר ליישום עותק עמוק של אובייקט היא באמצעות סידור. אתה יכול גם למנף השתקפות לביצוע עותק עמוק של מופע של כיתה. קטע הקוד הבא ממחיש כיצד ניתן לכתוב שיטה המיישמת סדרת בינארית לביצוע עותק עמוק של מופע באמצעות C #.

public static T DeepCopy(T obj)

       {

           if (!typeof(T).IsSerializable)

           {

               throw new Exception("The source object must be serializable");

           }

           if (Object.ReferenceEquals(obj, null))

           {

               throw new Exception("The source object must not be null");

           }

           T result = default(T);

           using (var memoryStream = new MemoryStream())

           {

                var formatter = new BinaryFormatter();

               formatter.Serialize(memoryStream, obj);

               memoryStream.Seek(0, SeekOrigin.Begin);

               result = (T)formatter.Deserialize(memoryStream);

               memoryStream.Close();

           }

           return result;

       }

בהתחשב בכך שיש לך מחלקת ישויות בשם עובד, תוכל לבצע עותק עמוק של מופע של מחלקת העובדים כפי שמוצג בקטע הקוד שלמטה.

static void Main(string[] args)

       {

           Employee emp = new Employee();

           emp.EmployeeId = 1;

           emp.FirstName = "Joydip";

           emp.LastName = "Kanjilal";

           Employee clone = DeepCopy(emp);

           if(Object.ReferenceEquals(emp, clone))

           {

               Console.WriteLine("References are the same.");

           }

           else

           {

               Console.WriteLine("References are different.");

           }

       }

בעת ביצוע התוכנית לעיל, יבוצע עותק עמוק של המופע "emp" וההודעה "הפניות שונות." יוצג.