被装箱的值类型在你认为你已经分布了无法被更改的原物复制类型的情况下是能够被更改的。在你返回一个被装箱的值类型的时候,其实你是在返回一个到值类型本身的引用,而不是对于这个值类型的复制的引用。这将允许在你的代码进行调用的用户代码中更改变量的值。
下列范例说明了如何使用引用来更改被装箱的值类型。
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 ClassC#
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
浙公网安备 33010602011771号