当前位置: 代码迷 >> C# >> 概念有关问题 类参数传入后改变
  详细解决方案

概念有关问题 类参数传入后改变

热度:63   发布时间:2016-05-05 04:03:54.0
概念问题 类参数传入后改变
有一个类
Class A{a="",b="",c=""}

一个方法
static void setvalue(A a)
{
       A newa=new A();
        newa.a=1
        newa.b=2
        newa.c=3
        a=newa;
}

执行 
       A a = new A();
       setvalue(a)
       // 在此处查看参数a,为什么没有变化?
方法内的引用替换没成功?

------解决思路----------------------
所谓 byref 传参,就是在调用方法之后将堆栈弹出的对象再赋值给原始的引用变量。也就是这里  void setvalue(ref A a) 这种结果。而所谓的 byval 传参,就是在调用方法之后直接丢弃从堆栈弹出的对象,不进行赋值。不论 A 是值类型还是引用类型,都是一样的机制。

因此在 .net 平台下,byval 通常会比 byref 更快,并且显然也更清晰。除非必要否则不要使用 byref、out。

注意这跟传统的c语言的指针引用是完全不一样的机制。有些人胡乱把c/c++语言的指针机制套用到byref上,虽然有点形似,但是其实是不一样的机制。


------解决思路----------------------
C#默认是传值的,这里的值不是object的值,而是ojbect的引用的值。

      A a = new A();
       setvalue(a);     //这里a 执行ObjectA

static void setvalue(A b)   //为了演示,改成b
{
      //这里b这个引用的只和外面的a的值是不同的,但是都指向同一个object  ObjectA. 类似于指针的概念。
       A newa=new A();    //new 了一个新的Object, 叫它OjbectB吧。赋给引用newa.
        newa.a=1
        newa.b=2
        newa.c=3
        b=newa;   //这里把newa引用的值赋给b, b指向ObjectB。但是外面的a引用没有变。
}

如果你要修改引用本身的值,使用ref。 ref的意思是传地址。


static void setvalue(ref A b)  //把实际参数的地址传进来了
{   
       A newa=new A();    
        newa.a=1
        newa.b=2
        newa.c=3
        b=newa;     //修改的是实际参数的值。
}
  相关解决方案