ASP.NET Lab

The Best Web, The Best Future

博客园 首页 新随笔 订阅 管理

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

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

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
posted on 2007-02-06 11:45  Laeb  阅读(269)  评论(0编辑  收藏  举报