.NET 指南:被装箱的值类型

被装箱的值类型在你认为你已经分布了无法被更改的原物复制类型的情况下是能够被更改的。在你返回一个被装箱的值类型的时候,其实你是在返回一个到值类型本身的引用,而不是对于这个值类型的复制的引用。这将允许在你的代码进行调用的用户代码中更改变量的值。

下列范例说明了如何使用引用来更改被装箱的值类型。

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

转载于:https://www.cnblogs.com/Laeb/archive/2007/02/06/641879.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值