在C#中,对象是通过值还是通过引用传递的?困惑!!! [英] In C# objects are passed by value or by reference ? Confused !!!

查看:187
本文介绍了在C#中,对象是通过值还是通过引用传递的?困惑!!!的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

public class Class1
    {
        private int Prop1;

        public int MyProperty1
        {
            get { return Prop1; }
            set { Prop1 = value; }
        }
    }

    protected void Button2_Click(object sender, EventArgs e)
    {
        Class1 oClass1 = new Class1();
        oClass1.MyProperty1 = 10;
        MethodCall(oClass1);
        TextBox2.Text = oClass1.MyProperty1.ToString();
    }

    public void MethodCall(Class1 oclass)
    {
        oclass.MyProperty1 = 100;
    }





上面的代码将TextBox.Text设为100.

这些值在将class1对象作为参数但不通过引用获取的函数。但是方法中的值的变化仍然反映在调用方法中。

这不会发生在int或Int32中。



有人可以请解释原因?

提前谢谢。



添加代码块以保留格式 - OriginalGriff [/ edit]



Above code gives TextBox.Text as 100.
These values are changed in a function which gets class1 object as parameter but not by reference. But still change in value in method is reflected in calling method.
This doesn't happen with int or Int32.

Can anybody please explain me the reason ?
Thanks in advance.

[edit]Code block added to preserve formatting - OriginalGriff[/edit]

推荐答案

哦,男孩 - 如果没有图片,这将很难解释,所以你最好还是看书。但是:



在您的单击处理程序中,您创建了Class1的实例,并将其分配给名为oClass1的变量。 oClass1实际上是什么?它是一个int - Class1存储的总数据吗?或者是其他什么?

oClass1中实际存储的内容不是实际的Class1实例 - 它是对类实例的引用。即您创建的实例位于堆上,而oClass1(可能)位于堆栈上。为什么?因此,如果需要,可以使用第二个变量:

Oh boy - this is going to be difficult to explain without pictures, so you would be better off looking in a book. But:

In your click handler, you create an instance of Class1, and assign it to a variable called oClass1. What is actually in oClass1? Is it an int - the total data stored by Class1? Or is it something else?
What is actually stored in oClass1 is not the actual Class1 instance - it is a reference to the class instance. I.e. the instance you created is on the heap and oClass1 is (probably) on the stack. Why? So that you could have a second variable if you needed it:
protected void Button2_Click(object sender, EventArgs e)
{
    Class1 oClass1 = new Class1();
    Class1 oClass2 = oClass1;
    oClass1.MyProperty1 = 10;
    MethodCall(oClass1);
    TextBox2.Text = oClass1.MyProperty1.ToString();
}

然后oClass1和oClass2都会引用Class1的同一个实例。

到目前为止和我在一起?好。

然后您将oClass1的内容交给您的方法。什么被传递?答案:对实例的引用。不是oClass1,而是oClass1的内容。

因此当您在MethodCall中修改MyProperty时,您正在修改oClass1引用的对象。



用图片来解释这个问题要容易得多!



尝试这个,你可能会看到我的意思:

And then both oClass1 and oClass2 would refer to the same instance of a Class1.
With me so far? Good.
You then hand the content of oClass1 to your method. What gets handed through? Answer: the reference to the instance. Not oClass1, but the content of oClass1.
So when you modify MyProperty in MethodCall you are modifying the object that oClass1 refers to.

This is a lot easier to explain with pictures!

Try this and you might see what I mean:

class Class1 { public int i;}
private void ShowTheDifference()
    {
    Class1 cs = new Class1();
    cs.i = 100;
    Method(cs);
    MessageBox.Show(cs.i.ToString());
    Method2(cs);
    MessageBox.Show(cs.i.ToString());
    }
void Method(Class1 cs) { cs = new Class1(); cs.i = 999; }
void Method2(Class1 cs) { cs.i = 999; }


ValueTypes以外的任何内容都通过引用传递。 ValueTypes包括结构。

Int32是一个结构,所以它是按值传递的。



你的自定义对象TextBox或任何对象(不是ValueType)是总是通过参考传递。
Anything other than ValueTypes are passed by reference. ValueTypes includes structures.
Int32 is a structure, so it is passed by value.

Your custom object TextBox or any object (which is not ValueType)is always passed by Reference.


不!值,值和引用类型都按值传递,除非您要求它们通过引用传递( ref out 关键字)。由于 Class1 是引用类型,因此是指向存储在堆上的某个对象的引用。因此,在 MethodCall 中更改对oclass的引用属性的值会更改 oclass.MyProperty 的值。堆。



No! Both, value and reference types are passed by value unless you require them to be passed by reference (the ref or out keywords). Since Class1 is a reference type its value is a reference pointing to some object stored on the heap. Thus, changing the value of a property of a reference to oclass in MethodCall changes the value of oclass.MyProperty on the heap.

public void MethodCall(Class1 oclass)    {        oclass.MyProperty1 = 100;    }





如果你想通过引用传递 ref





If you want to pass by reference use ref:

public void MethodCallByRef(ref Class1 oclass) {
int tOldValue = oclass.MyProperty1;
oclass = new Class1();
oclass.Property1 = tOldValue;
}





那么你有:





then you have:

...

Class1 o1 = new Class1();
Class1 o2 = o1;

MethodCall(o2);

Console.Write(Object.Equals(o1.Property1, o2.Property1));// prints true
Console.Write(Object.ReferenceEquals(o1, o2)); // prints true

MethodCallByRef(ref o2); // explicit call by reference!

Console.Write(Object.Equals(o1.Property1, o2.Property1)); // prints true!
Console.Write(Object.ReferenceEquals(o1, o2)); // prints false!
...


这篇关于在C#中,对象是通过值还是通过引用传递的?困惑!!!的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆