[Zope-CVS] CVS: PythonNet - README.txt:1.13

Brian Lloyd brian at zope.com
Sat Jan 17 23:30:06 EST 2004

Update of /cvs-repository/PythonNet
In directory cvs.zope.org:/tmp/cvs-serv26381

Modified Files:
Log Message:
Checkin miscellaneous stuff done since Nov.

=== PythonNet/README.txt 1.12 => 1.13 ===
--- PythonNet/README.txt:1.12	Wed Nov 19 22:30:34 2003
+++ PythonNet/README.txt	Sat Jan 17 23:29:35 2004
@@ -412,6 +412,81 @@
       are returned as unicode.
+    **Value Types And Reference Types**
+      The .NET architecture makes a distinction between 'value types' and 
+      'reference types'. Reference types are allocated on the heap, and 
+      value types are allocated either on the stack or in-line within an 
+      object.
+      A process called 'boxing' is used in .NET to allow code to treat a
+      value type as if it were a reference type. Boxing causes a separate 
+      copy of the value type object to be created on the heap, which then 
+      has reference type semantics.
+      Understanding boxing and the distinction between value types and 
+      reference types is important when using Python for .NET because 
+      the Python language has no value type semantics or syntax - in 
+      Python "everything is a reference". This difference can be important 
+      in certain situations when you are writing code dealing with 
+      managed value types.
+      Here is a simple example that demonstrates the issue. If you are an 
+      experienced C# programmer, you might write the following code::
+        items = CLR.System.Array.CreateInstance(Point, 3)
+          for i in range(3):
+            items[i] = Point(0, 0)
+        items[0].X = 1 # won't work!!
+      While the spelling of 'items[0].X = 1' is the same in C# and Python,
+      there is an important and subtle semantic difference. In C# (and other
+      compiled-to-IL languages), the compiler knows that Point is a value
+      type and can do the Right Thing here, changing the value in place.
+      In Python however, "everything's a reference", and there is really no
+      spelling or semantic to allow it to do the right thing dynamically. The
+      specific reason that 'items[0]' itself doesn't change is that when you
+      say 'items[0]', that getitem operation creates a Python object that
+      holds a reference to the object at 'items[0]' via a GCHandle. That causes
+      a ValueType (like Point) to be boxed, so the following setattr ('.X = 1')
+      *changes the state of the boxed value, not the original unboxed value*.
+      The rule in Python is essentially: "the result of any attribute or 
+      item access is a boxed value", and that can be important in how you 
+      approach your code.
+      Because there are no value type semantics or syntax in Python, you 
+      may need to modify your approach. To revisit the previous example, 
+      we can ensure that the changes we want to make to an array item 
+      aren't "lost" by resetting an array member after making changes 
+      to it::
+        items = CLR.System.Array.CreateInstance(Point, 3)
+          for i in range(3):
+            items[i] = Point(0, 0)
+	# This _will_ work. We get 'item' as a boxed copy of the Point
+        # object actually stored in the array. After making our changes
+        # we re-set the array item to update the bits in the array.
+        item = items[0]
+        item.X = 1
+        items[0] = item
+      This is not unlike some of the cases you can find in C# where you have
+      to know about boxing behavior to avoid similar kinds of 'lost update'
+      problems (generally because an implicit boxing happened that was not
+      taken into account in the code).
+      This is the same thing, just the manifestation is a little different
+      in Python. See the .NET documentation for more details on boxing and 
+      the differences between value types and reference types.
       Because Python code is inherently unverifiable, Python code runs 

More information about the Zope-CVS mailing list