2 out of 4 rated this helpful - Rate this topic

Boxed Value Types 

Boxed value types can sometimes be modified in cases where you think you have distributed a copy of the type that cannot modify the original. When you return a boxed value type, you are returning a reference to the value type itself, rather than a reference to a copy of the value type. This allows the code that called your code to modify the value of your variable. For more information about boxed value types, see Boxing and Unboxing (C# Programming Guide).

The following example shows how boxed value types can be modified using a reference.

using System; 
using System.Reflection; 
using System.Reflection.Emit;
using System.Threading; 
using System.Collections; 
class bug {
// Suppose you have an API element that exposes a 
// field through a property with only a get accessor.
public object m_Property;
public Object Property {
    get { return m_Property;}
    set {m_Property = value;} // (if applicable)
}
// You can modify the value of j by using 
// the byref method with this signature.
public static void m1( ref int j ) {
    j = Int32.MaxValue;
}
public static void m2( ref ArrayList j )
{
    j = new ArrayList();
}
public static void Main(String[] args)
{
    Console.WriteLine( "////// doing this with a value type" );
    {
        bug b = new bug();
        b.m_Property = 4;
        Object[] objArr = new Object[]{b.Property};
        Console.WriteLine( b.m_Property );
        typeof(bug).GetMethod( "m1" ).Invoke( null, objArr );
        // Note that the property changes.
        Console.WriteLine( b.m_Property ); 
        Console.WriteLine( objArr[0] );
    }
    Console.WriteLine( "////// doing this with a normal type" );
    {
        bug b = new bug();
        ArrayList al = new ArrayList();
        al.Add("elem");
        b.m_Property = al;
        Object[] objArr = new Object[]{b.Property};
        Console.WriteLine( ((ArrayList)(b.m_Property)).Count );
        typeof(bug).GetMethod( "m2" ).Invoke( null, objArr );
        // Note that the property does not change.
        Console.WriteLine( ((ArrayList)(b.m_Property)).Count ); 
        Console.WriteLine( ((ArrayList)(objArr[0])).Count );
    }
}
}

The previous code displays the following to the console:

////// doing this with a value type
4
2147483647
2147483647
////// doing this with a normal type
1
1
0

See Also

Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ
Just a poor example in general
It would be easier to understand and also more obvious why it doesn't work properly if reflection wasn't used.
Incorrect example

This is the result I am getting too.

////// doing this with a value type
4
4
2147483647
////// doing this with a normal type
1
1
0

Example incorrect agreement
I get the same output as the poster above on Visual Studio 2005 SP1 with .Net 2.0 SP1
Example incorrect?

I ran the C# example with Visual C# 2008 Express Beta 2. I received the following output, which contradicts what this article says:

////// doing this with a value type

4

4

2147483647

////// doing this with a normal type

1

1

0

Is this security hole for real?