Why can I not modify the result of an unboxing conversion?

Solution 1:

Because of how value types work, the boxed Point is a copy of the original, and "unboxing" it by casting back to Point creates yet another copy. From the C# language spec (§1.3, "Types and Variables"):

When a value of a value type is converted to type object, an object instance, also called a “box,” is allocated to hold the value, and the value is copied into that box. Conversely, when an object reference is cast to a value type, a check is made that the referenced object is a box of the correct value type, and, if the check succeeds, the value in the box is copied out.

Modifying the copy wouldn't change the original anyway, so it wouldn't make much sense to allow it.

As for C++...well...of course, the rules of C# don't necessarily apply to it. :) The CLR actually has quite a bit more flexibility with pointers and references than you'd first think, and C++ -- being known for such flexibility -- probably takes advantage of it.

Solution 2:

You can't do this, because the result of unboxing is a copy of the boxed value, not the boxed value itself. And casting object to a value type is the definition of unboxing. So, if the compiler allowed you to do this, it would be very confusing, because the assignments wouldn't actually do anything.

I think the reason your code works in C++/CLI is because that language in general has more support for working (or not) with references, including strongly-typed boxes (e.g. Point^) and treating (some) classes as value types (e.g. using MemoryStream without ^).