为什么赋值给参数不会改变对象?

时间:2014-05-10 19:49:54

标签: c# .net

classes deal with the reference types and traditional data types deal with the value type just for example :
int i=5;
int j=i;
i=3 ; //then this will output i=3 and j=5 because they are in the different memory blocks .

同样如果我们谈论一个类的对象说点类

class point
{
    public int x,y;
    void somefucnt(point p,int x)
    {
        Console.writeline("value of x is "+p.x);
        x=22;
        Console.writeline("value of x is "+p.x);
    }
}
class someotherclass
{
    static void Main(string [] args )
    {
        p1.x=10;
        p1.somefunct(p1,p1.x); 
    }
}

两个console.write语句都打印10,尽管我已将x更改为其他值?为什么会这样?因为p只是对x的引用所以应该通过改变x的值来更新它。这件事让我很困惑。

4 个答案:

答案 0 :(得分:0)

void somefucnt(point p,int x){
Console.writeline("value of x is "+p.x);

x=22;
Console.writeline("value of x is "+p.x);

}

此处,x=22不会更改p.x,但x的参数(point p,int x)会发生变化c# this 通常,您对值/引用的假设是正确的(如果我理解正确的话)。

提示:Google为{{1}}而不是将对象传递给自己的方法

答案 1 :(得分:0)

您更改参数(x)的值,而不是p.x的值,除非您使用ref关键字,否则值类型会按值传递。

与第一个例子中一样,ij以及参数xp1.x之间没有任何关系。每个变量都有它'在记忆中拥有自己的空间。改变其中一个并不影响另一个。

答案 2 :(得分:0)

x函数中有两个名为somefucnt的变量。一个是您尝试更改的成员变量x,另一个是void somefucnt(point p, int x)中的函数输入参数。当您说x = 22时,输入参数x将被更改,而不是成员变量x。

如果您将行x = 22更改为this.x = 22,那么它应该可以正常运行。

旁注:

避免混淆的一个好方法是始终将类成员设为私有,并将其命名为_x。否则,在CamelCase中拥有公共自动属性,如下所示:

public int X { get; set; }

这些方法避免了类变量和函数输入变量之间的歧义。

答案 3 :(得分:0)

观察到的行为 nothing 与值类型与引用类型有关 - 它在调用方法时与Evaluation of Strategy(或“调用约定”)有关。

没有ref/out,C#总是 Call by Value 1 ,这意味着对参数的重新分配不会影响调用者绑定。因此,重新分配给x 参数与参数值(或此类值的来源)无关 - 无论是值类型还是引用类型都无关紧要

请参阅Reference type still needs pass by ref?(关于调用者未查看参数重新分配的原因):

  

一切都是通过C#中的值传递的。但是,当您传递引用类型时,引用本身将按值传递,即传递原始引用的副本。因此,您可以更改引用副本指向的对象的状态,但是如果为引用[参数]分配新值,则只会更改[局部变量]副本指向的内容,而不是原始引用[在论证表达中]。

Passing reference type in C#(关于为什么ref不需要改变引用类型)

  

即。对象的地址按值传递,但对象和对象的地址是相同的。因此,当您调用方法时,VM会复制引用;你只是在改变副本。


1 对于引用类型,短语“[参考值]的调用值”或“[参考值]调用值”可以帮助解决问题。 Eric Lippert撰写了一篇热门文章The Truth about Value Types,鼓励将参考值视为参考文献(或参考类型实例)的独特概念。