ボックス化変換された型
型のコピーを配布し、それが元の型を変更できないようなケースのときに、ボックス化変換された型を変更することがあります。ボックス化変換された型を返すときは、値型のコピーへの参照ではなく、その値型自体への参照を返します。これによって、呼び出し元のコードが変数の値を変更できるようになります。
参照を使用してボックス化変換された型を変更する方法の例を次に示します。
Imports System
Imports System.Reflection
Imports System.Reflection.Emit
Imports System.Threading
Imports System.Collections
_
Class bug
' Suppose you have an API element that exposes a
' field through a property with only a get accessor.
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
' You can modify the value of j by using
' the byref method with this signature.
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
'Entry point that delegates to C-style main private function.
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)
' Note that the property changes.
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)
' Note that the property does not change.
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 {
// 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 );
}
}
}
上のコードは、コンソールに次のように出力します。
////// doing this with a value type
4
2147483647
2147483647
////// doing this with a normal type
1
1
0