解释下unboxinterface IA
{
void b();
}
struct B : IA
{
public int n = 3;
public void b()
{
a = 2;
}
public static void main(Sting[] args)
{
B b = new B();
Object o = b;
(B)0.b();
System.out.println((B)0.n); //这里是3,而不是2;这是个unbox 问题,我知道
//unbox不会复制,就是这点让我很难理解
}
}
没办法,只能拿出这么多
{
void b();
}
struct B : IA
{
public int n = 3;
public void b()
{
a = 2;
}
public static void main(Sting[] args)
{
B b = new B();
Object o = b;
(B)0.b();
System.out.println((B)0.n); //这里是3,而不是2;这是个unbox 问题,我知道
//unbox不会复制,就是这点让我很难理解
}
}
没办法,只能拿出这么多
interface IA
{
void A();
} struct B : IA
{
public int N;
public B(int t)
{
N = t;
}
public void A()
{
N = 3;
} } public class Program
{
static void Main()
{
B b = new B(1);
object o = b;
((B)o).A();
Console.Write(((B)o).N);
Console.ReadKey(); }
}
装箱是将值类型转换为 object 类型或由此值类型实现的任一接口类型的过程。装箱转换示意图:
struct B 是值类型,存储在堆栈上。
object o = b;这里会在堆栈上声明一个引用o,同时会把堆栈上的b,复制一份到堆上。并将堆栈上的引用o指向堆中的b。(这时候会有2个b对象,一个是栈上的b,一个是复制到堆上的b)。
通过引用o去修改的是堆上的b,栈上的值类型b并没有被修改。
所以会有上面的结果。 interface A
{
void test();
} struct B : A
{
public int N;
public B(int n)
{
this.N = n;
}
public void test()
{
N = 10;
}
}
直接用父类接口来装箱,可能好理解一点。 static void Main(string[] args)
{
B b = new B(1);//再栈上声明一个 B 对象
A a = b;//在堆上声明一个引用 a ,并把栈上的 b 对象复制到堆中
//把 a 指向堆中的 b 对象。
a.test();//通过引用 a 修改堆上的对象
Console.WriteLine(b.N);//这是栈中的对象,没有被改变。
Console.WriteLine(((B)a).N);//这是堆中的对象,值改变了。
}
object o = b;
((B)0).A(); //这应该是拆箱,拆箱时不会从堆上的对象复制,那它修改是哪里。
//拆箱就改变下引用,那后面有一个(B)0,
我感觉就是o = b永远不变,而每一次拆箱是从推复制到栈上,每次都分一块内存,所以第二次输出没有改变。这里我的疑问就是,拆箱不复制,搞不懂。
我以为已拆箱就变成原来栈上的那个对象,我用IA a = new B(1); //cil中new是init,我就认为这是先在栈上分了一块,然后又复制到堆上
//不知道我理解有没有问题
a.A();
Console.WriteLine((B)a).N) //这变成3,说没有变成原先那个栈上的,而是复制了,
//就是我理解的复制让我转不过来,拆箱不复制,那是修改引用,
//实在想不通