Condividi tramite


Tipi valore boxed

I tipi valore boxed possono essere modificati quando si ritiene di avere distribuito una copia del tipo che non consente la modifica dell'originale. Quando si restituisce un tipo valore boxed, viene restituito un riferimento allo stesso tipo valore invece di un riferimento a una copia del tipo valore. In questo modo sarà possibile modificare il valore della variabile dal codice da cui viene richiamato il codice generato.

Nell'esempio riportato di seguito è dimostrato come i tipi valore boxed possano essere modificati tramite un riferimento.

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 which 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 );
    }
}
}

Il codice precedente consente la visualizzazione nella console di quanto riportato di seguito.

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

Vedere anche

Indicazioni per la generazione di codice protetto