الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

The C# Value Type and Boxing

مغلق
بدأه Ahmed H. Alawady في 29 يونيو 2006 · 3 رد · 966 مشاهدة · في Microsoft Visual C#.NET
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

هذا الدرس متعلق ومرتبط بسلسلة دروس Heap و Stack

Even though with the .NET framework we don't have to actively worry about memory management and garbage collection (GC), we still have to keep memory management and GC in mind in order to optimize the performance of our applications.  One of the things we need to be aware of is how the Common Language Runtime (CLR) deals with references to value types. 

When an instance of a value type is converted to a System.Object type or to an interface, the CLR needs to convert the value type to a valid reference type.  Memory is allocated on the managed heap and the object is copied over.  We need to be aware of this for two reasons: boxing is a very expensive process (copying a whole object from the stack to the heap uses up processor cycles and space on the managed heap) and we now have two objects in memory that can have conflicting states.

Here is a simple example of boxing.

int i = 0;

object obj = (object) i; // i is boxed here
obj = ((int) i) + 3; // changing i on the heap
i += 1; // changing i on the stack

Console.WriteLine(obj.ToString());
Console.WriteLine(i.ToString());

Gives us the result:

boxing1.gif

Here is a play-by-play of what happens

Step 1:  i is placed on the stack

boxing2.gif

Step 2:  i is copied to the heap (boxed) and obj goes on the stack, the value of obj is the memory address of the new object on the heap (a pointer).

boxing3.gif

Step 3:  The value of obj is updated and now contains the value 3

boxing4.gif

Step 4:  i (the one on the stack) is updated and now contains the value 1

boxing5.gif

Here is a more complex example:

class Class1

{

		  [STAThread]

		  static void Main(string[] args)

		  {

				   MyInt test = new MyInt();

				   test.value = 100;

				   test.AddOne();

				   aDelegate del = new aDelegate(test.AddOne);

				   del();

				   test.AddOne();

		  }

}

public delegate void aDelegate();

public struct MyInt

{

		  public int value;

		  public void AddOne()

		  { 

					Console.WriteLine(string.Format("Before: {0}", value.ToString()));

					value += 1; 

					Console.WriteLine(string.Format("After : {0}", value.ToString()));

		  }

}

Here's the output:

boxing6.gif

Not the result you were expecting, right? What's going on?  Let's walk through what happens. After Main() and args[] are placed on the stack and the Main method begins execution:

Step 1:  test is placed on the stack

boxing7.gif

Step 2:  AddOne() is placed on the stack and executed.  Changing the value of MyInt.value to 101;

boxing8.gif

Step 3:  AddOne() is removed from the stack and MyInt is boxed (copied) to the heap. Del now points to the heap version of the object.

boxing9.gif

Step 4: AddOne() is called from the boxed object, updating it's value to 102.

boxing10.gif

Step 5: AddOne() from the heap is removed.

boxing11.gif

Step 6: AddOne() from the stack version of MyInt is added to the stack, changing it's value to 102.

boxing12.gif

Finally: Main is done executing and cleared off the stack.  The object left in the heap is ready for Garbage Collection (GC).

boxing13.gif

Let's make a change to improve the performance of our application and get results that make more sense. If we make MyInt into a reference type, we'll be dealing with one object on the heap and there will be no boxing. 

public class MyInt

{

		  public int value;

		  public void AddOne()

		  { 

				   Console.WriteLine(string.Format("Before: {0}", value.ToString()));

				   value += 1; 

				   Console.WriteLine(string.Format("After : {0}", value.ToString()));

		  }

}


With this change we get results closer to what we are expecting:

Before: 100 
After : 101
Before: 101
After : 102
Before: 102
After : 103

In Conclusion

More unexpected places boxing shows up is when we call ToString() or GetType()  on a value type.  In this case the method is called through the base object (System.Object) and therefore boxing is required before the method is accessible.  Boxing also shows up when we place value objects into an ArrayList() (in which case they are typecast to System.Object).  As you can imagine, the boxing process can be very expensive if done repeatedly on a large scale.

Hopefully this article gave you a better understanding of how value types are boxed and what to watch out for when dealing with value types through references like interfaces, delegates, or when they are put in an ArrayList.

Until next time,

-Happy coding

المرفقات

boxing.zip

Name : Ahmed H. Alawady

Web Site : Alawady.info

Email : alawady_ahmed@hotmail.com

Tel : +2 012 345 6808

#2

الف شكر اخي احمد علي المقالات الرائعه

ولكن عندي سؤال ماهو الفرق بين الImplicit and Explicit Boxing

واي من هذه هي الimplicit واي منهما Explicit

object obj = (object) i; // i is boxed here
obj = ((int) i) + 3; // changing i on the heap

تم تعديل هذه المشاركة بواسطة khaled_tiger في 29 يونيو 2006 في 19:13

Khaled_Tiger

النجاح الوحيد في الحياة هو أن تستطيع أن تحيا حياتك بالطريقة التي تريدها

يخاطبني السفيه بكل قبح *** فأكره أن أكون له مجيبا

يزيد سفاهة فأزيد حلمــا *** كعود زاده الإحراق طيبا

إذا نطق السفيه فلا تجبه *** فخير من إجابته السكوت

فإن كلَمته فرَجت عنــــه *** وإن خليته كمداً يـمـــوت

#3

السلام عليكم ورحمة الله وبركاته

هذا هو الفرق بينهم

Int32 x = 10; 
		object o = x;  // Implicit boxing
		Console.WriteLine("The Object o = {0}",o); // prints out 10
		//-----------------------------------------------------------
		Int32 x = 10; 
		object o = (object) x; // Explicit Boxing
		Console.WriteLine("The object o = {0}",o); // prints out 10

khaled_tiger كتب:
واي من هذه هي الimplicit واي منهما Explicit

object obj = (object) i; // i is boxed here
obj = ((int) i) + 3; // changing i on the heap

الأثنين Explicit

Name : Ahmed H. Alawady

Web Site : Alawady.info

Email : alawady_ahmed@hotmail.com

Tel : +2 012 345 6808

#4

السلام عليكم ورحمة الله وبركاته

جزاك الله خيرا اخي احمد ووفقك لما هو خير ان شاء الله

Khaled_Tiger

النجاح الوحيد في الحياة هو أن تستطيع أن تحيا حياتك بالطريقة التي تريدها

يخاطبني السفيه بكل قبح *** فأكره أن أكون له مجيبا

يزيد سفاهة فأزيد حلمــا *** كعود زاده الإحراق طيبا

إذا نطق السفيه فلا تجبه *** فخير من إجابته السكوت

فإن كلَمته فرَجت عنــــه *** وإن خليته كمداً يـمـــوت

هذا الموضوع مغلق.

مواضيع مشابهة