有一个类
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,为什么没有变化?
方法内的引用替换没成功?
|
|
首先,你根本没有改变传入的a对象的属性,所以传这个参数是多余的。
其次,你是使用 byval 方式传递的对象。你可以试一下:
static void setvalue(ref A a){.......}
不过如果真的需要这样,人家就定义
static A CreateA(){.....}
了。
|
|
通常会写成这样
static void Create()
{
A newa=new A();
newa.a=1;
newa.b=2;
newa.c=3;
return newa;
}
A a = CreateA();
其实往往是知识越多越容易乱写。
|
11分 |
所谓 byref 传参,就是在调用方法之后将堆栈弹出的对象再赋值给原始的引用变量。也就是这里 void setvalue(ref A a) 这种结果。而所谓的 byval 传参,就是在调用方法之后直接丢弃从堆栈弹出的对象,不进行赋值。不论 A 是值类型还是引用类型,都是一样的机制。
因此在 .net 平台下,byval 通常会比 byref 更快,并且显然也更清晰。除非必要否则不要使用 byref、out。
注意这跟传统的c语言的指针引用是完全不一样的机制。有些人胡乱把c/c++语言的指针机制套用到byref上,虽然有点形似,但是其实是不一样的机制。
|
29分 |
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; //修改的是实际参数的值。
}
|
|
ref
out
请了解各种关键字
|
|
应该是这样:
static A Create(){}
void是没法return newa的
|
|
有一个类
class A
{
public int a, b, c;
}
一个方法
static void setvalue(A a)
{
a.a = 1;
a.b = 2;
a.c = 3;
}
执行
A a = new A();
setvalue(a);
Console.WriteLine(“a={0} b={1} c={2}”, a.a, a.b, a.c);
楼主初学,我也初学。我就不喜欢有人非要把问题往深里引,把一个简单的问题弄得异常复杂
|
|
用ref,C#基础的东西
|
|
这两句话不太明白,b是A类的实例”a”的一个引用,传入这个引用,相当于传入实例”a”?,但你说”这里b这个引用的只和外面的a的值是不同的“,这想不通,当前认为,传入这个类的某个实例,那就是这个实例本身
|
|
在方法中,我将a实例的引用指向 ,直接改成了新new的实例,就是不想一个个属性赋值,但这样为什么不行.
|
|
这个我试过呀,是可以的.
在执行方法里新NEW 那个A对象,其数据是来自XML的,并且属性超过18个,总不能给参数对象赋值18回吧.这多不科学
|
|
都告诉你加ref了
|
|
sp1234
和宝_小孩
就差一点了,我就明白了
|
|
实例是不会被传入函数的。
lz可能没有接触过指针。
A newa=new A(); newa 分配在堆栈上,其类型可能是int32.是指向object的地址。我所说的值是指这个地址。
static void setvalue(A b) //传入函数时, b也分配在堆栈上,调用函数时,newa的指向object的地址被传到b上,这是我所说的传值, 外面newa和b,不在同样的位置上,但是值是相同的(指向object的地址。
….
b=newa; b这个位置上的值变成指向新的object地址了, 外面的newa却没有改变。
这下应该明白了吧。
|
|
我在 #7 已经演示了对象的引用传值
你那样写不行的原因是:
a = newa;
将切断了传入参数 a 对调用时传递的 a 的引用关系(此 a 非彼 a)
对于你的这种写法,需要
在方法中声明 ref(引用) static void setvalue(ref A a)
在调用时声明 ref(引用) setvalue(ref a)
或者同时声明为 out
static void setvalue(out A a)
setvalue(out a)
C#的对象都是传递引用的,根本没有不要使用 ref、out 关键字的必要
而这两个关键字是为不是对象的变量准备的(C#中都是对象,应该是没有用武之地了)
|
|
实例是不会被传入函数的。
lz可能没有接触过指针。
A newa=new A(); newa 分配在堆栈上,其类型可能是int32.是指向object的地址。我所说的值是指这个地址。
static void setvalue(A b) //传入函数时, b也分配在堆栈上,调用函数时,newa的指向object的地址被传到b上,这是我所说的传值, 外面newa和b,不在同样的位置上,但是值是相同的(指向object的地址。
b=newa; b这个位置上的值变成指向新的object地址了, 外面的newa却没有改变。
这下应该明白了吧。
是的.明白了.
A类有两个实例,在堆中
A类的引用在栈中,改变引用不会改变堆中的实例,通过引用可能改变堆中实例的属性
并且 实例是不会被传入函数的。
|
|
我在 #7 已经演示了对象的引用传值
你那样写不行的原因是:
a = newa;
将切断了传入参数 a 对调用时传递的 a 的引用关系(此 a 非彼 a)
对于你的这种写法,需要
在方法中声明 ref(引用) static void setvalue(ref A a)
在调用时声明 ref(引用) setvalue(ref a)
或者同时声明为 out
static void setvalue(out A a)
setvalue(out a)
C#的对象都是传递引用的,根本没有不要使用 ref、out 关键字的必要
而这两个关键字是为不是对象的变量准备的(C#中都是对象,应该是没有用武之地了)
感谢
最不喜欢rel 和 out
|