被装箱的值类型在你认为你已经分布了无法被更改的原物复制类型的情况下是能够被更改的。在你返回一个被装箱的值类型的时候,其实你是在返回一个到值类型本身的引用,而不是对于这个值类型的复制的引用。这将允许在你的代码进行调用的用户代码中更改变量的值。
下列范例说明了如何使用引用来更改被装箱的值类型。
Visual Basic
Imports System Imports System.Reflection Imports System.Reflection.Emit Imports System.Threading Imports System.Collections Class bug ' 假设你持有只以一个 get 访问器而通过属性来暴露字段的 API 元素。 Public m_Property As Object Public Property [Property]() As [Object] Get Return m_Property End Get Set m_Property = value ' (if applicable) End Set End Property ' 你能够通过这个签名而使用 byref 方法来更改 j 的值。 Public Shared Sub m1(ByRef j As Integer) j = Int32.MaxValue End Sub Public Shared Sub m2(ByRef j As ArrayList) j = New ArrayList() End Sub 'm2 ' 委派到 C 风格的私有的主函数实体入口。 Public Overloads Shared Sub Main() Main(System.Environment.GetCommandLineArgs()) End Sub Overloads Public Shared Sub Main(args() As [String]) Console.WriteLine("////// doing this with a value type") If (True) Then Dim b As New bug() b.m_Property = 4 Dim objArr() As [Object] = {b.Property} Console.WriteLine(b.m_Property) GetType(bug).GetMethod("m1").Invoke(Nothing, objArr) ' 注意:属性已经改变。 Console.WriteLine(b.m_Property) Console.WriteLine(objArr(0)) End If Console.WriteLine("////// doing this with a normal type") If (True) Then Dim b As New bug() Dim al As New ArrayList() al.Add("elem") b.m_Property = al Dim objArr() As [Object] = {b.Property} Console.WriteLine(CType(b.m_Property, ArrayList).Count) GetType(bug).GetMethod("m2").Invoke(Nothing, objArr) ' 注意:属性没有改变。 Console.WriteLine(CType(b.m_Property, ArrayList).Count) Console.WriteLine(CType(objArr(0), ArrayList).Count) End If End Sub End Class
C#
using System; using System.Reflection; using System.Reflection.Emit; using System.Threading; using System.Collections; class bug { // 假设你持有只以一个 get 访问器而属通过属性来暴露字段的 API 元素。 public object m_Property; public Object Property { get { return m_Property;} set {m_Property = value;} // (if applicable) } // 你能够通过这个签名而使用 byref 方法来更改 j 的值。 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 ); // 注意:属性已经改变。 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 ); // 注意:属性没有改变。 Console.WriteLine( ((ArrayList)(b.m_Property)).Count ); Console.WriteLine( ((ArrayList)(objArr[0])).Count ); } } }
上述代码会在控制台中显示如下内容:
////// doing this with a value type 4 2147483647 2147483647 ////// doing this with a normal type 1 1 0