值类型和引用类型之间有什么区别 [英] what is the difference between value type and reference type

查看:87
本文介绍了值类型和引用类型之间有什么区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不了解值类型和引用类型的概念
我有以下代码,但我无法理解它的工作方式

I am not getting the concept of value type and reference type
I have following code but i am not able to understand it how it works

 struct Numbers
{
public int val;
public Numbers(int _val)
{ val = _val; }
public override string ToString()
{ return val.ToString(); }
}
Numbers n1 = new Numbers(0);
Numbers n2 = n1;
n1.val += 1;
n2.val += 2;
Console.WriteLine("n1 = {0}, n2 = {1}", n1, n2);


该代码将显示"n1 = 1,n2 = 2"




This code would display "n1 = 1, n2 = 2"

and

class Numbers
{
public int val;
public Numbers(int _val)
{ val = _val; }
public override string ToString()
{ return val.ToString(); }
}
Numbers n1 = new Numbers(0);
Numbers n2 = n1;
n1.val += 1;
n2.val += 2;
Console.WriteLine("n1 = {0}, n2 = {1}", n1, n2);


该代码将显示"n1 = 3,n2 = 3"

为什么和如何..
请帮助
预先感谢


This code would display "n1 = 3, n2 = 3"

why and how..
please help
Thanx in advance

推荐答案

结构是值类型对象,而类是引用类型对象.

当您声明一个Struct变量时,它被定义为值类型",即仅表示内存变量.如果是struct:

//变量1
数字n1 =新数字(0);

//变量2
数字n2 = n1;

也就是说,创建了一个新变量n2,其初始值等于n1.因此更改n2的值不会影响n2

另一方面,当您创建Class的新实例时,它被声明为Reference Type. n1的Object变量包含值的存储地址.

当您将n1分配给n2时,它只是将n1的内存地址复制到n2.而不是复制直接价值.这意味着值在另一个内存地址上,一个实例的值更改也会在其他实例中反映出来.
The Structs are Value type Object whereas class is an reference type object.

When you are declaring an variable of Struct it is defined as Value Type that means simply the memory variable. In case of struct:

// Variable 1
Numbers n1 = new Numbers(0);

// Variable 2
Numbers n2 = n1;

i.e. a new variable n2 created with value initialized equal to n1. so changing value of n2 would not affect n2

On other end when you create a new instance of Class it is declared as Reference Type. The Object variable of n1 contains a memory address for values.

When you assign n1 to n2, it simply copy the memory address of n1 to n2. Instead of copying direct value. That means value is on some-other memory address and change in value of one instance will reflect in other instance as well..


Charles Petzold在他的免费书.NET零本书 [ ^ ]给出了很好的解释.
Charles Petzold in his free book .NET Book Zero[^] gives an excellent explanation.


区别很简单,但很难解释,尤其是没有图片的情况.

从根本上讲,当您处理值类型时,您将传递实际的对象,或者复制实际的对象值.当您对引用类型进行相同操作时,您不需要-而是将引用传递给该对象.
拿几张纸.每个代表一个变量.
值类型:
取两张.在第一个标签上,将其标记为"n1"并写入一个值-在您的示例中为零.
在第二个上,将其标记为"n2",然后复制"n1"中的值
在"n1"上的值上加一个
在"n2"的值上加上两个

现在拍另外三张纸.在第一个标签上为"n1".获取第二张工作表,并将其标记为"Numbers:instance1"-在此工作表上写一个值,在您的示例中为零.
在标记为"n1"的工作表上,写入值"Numbers:instance1".这是对Numbers类的实际实例的引用.
在第三张纸上,将其标记为"n2",然后复制"n1"中的值.这将是对"Numbers:instance1"的引用
在"n1"的值上加一个-这意味着要遵循崇高的态度才能到达实际实例,因为您不能增加引用.这样,工作表"Numbers:instance1"的值为零+一=一.
在"n2"的值上加上两个-这意味着要遵循崇高的态度才能到达实际实例,因为您不能增加引用.这样,工作表"Numbers:instance1"的值为1 + 2 =3.

这有意义吗?


你能用一个例子向我解释一个问题吗?
将值类型变量作为过程的参数传递给过程.过程更改了变量,但是当过程返回时,变量没有改变.发生了什么

我认为其答案是将值类型传递给过程会创建数据的副本.
您能用例如这个答案正确的方法来解释吗?"




你很近,但还不很近.
当您使用值或引用调用方法时,该方法将获取变量的副本. (我在这里忽略了ref参数).区别在于要复制的变量的类型.
复制值类型时,将复制整个值-结构的所有元素.
复制参考类型时,仅复制参考.
不需要通过方法调用来显示此内容-复制变量的任何内容都可以:
The difference is pretty simple, but it is difficult to explain, particularly without pictures.

Fundamentally, when you deal with value type, you pass the actual object around, or you copy the actual object values. When you do the same with a reference type, you don''t - you pass a reference to the object instead.
Take some sheets of paper. Each one represents a variable.
Value type:
Take two sheets. On the first one, label it "n1" and write a value - in your example zero.
On the second one, label it "n2" and copy the value from "n1"
Add one to the value on "n1"
Add two to the value on "n2"

Now take three other sheets. On the first one label it "n1". Get a second sheet, and label it "Numbers:instance1" - write a value on this sheet, in your example, zero.
On the sheet you labelled "n1" write the value "Numbers:instance1" This is a reference to the actual instance of the Numbers class.
On the third sheet, label it "n2" and copy the value from "n1". This will be the reference to "Numbers:instance1"
Add one to the value on "n1" - this means follow the reverence to get to the actual instance, since you can''t increase a reference. This leaves the sheet "Numbers:instance1" holding the value zero + one = one.
Add two to the value on "n2" - this means follow the reverence to get to the actual instance, since you can''t increase a reference. This leaves the sheet "Numbers:instance1" holding the value one + two = three.

Does that make sense?


"Can u explain me one question with eg.
passing a value type variable into procedure as an argument.The procedure changes the variable,however when the procedure returns,the variable has not changed.What happened

I think its answer is that passing a value type into procedure creates a copy of the data.
Can u explain this with an e.g if this answer is correct"




You are close, but not quite there.
When you call a method with either a value or a reference, the method gets a copy of the variable. (I''m ignoring ref parameters here). The difference is in the type of the variable which is copied.
When you copy a value type, you copy the whole value - all of the elements of the structure.
When you copy a reference type you only copy the reference.
It doesn''t need to be a method call to show this - anything which copies the variable will do:
struct valtype
    {
    public int i;
    public string s;
    public valtype(int i, string s) { this.s = s; this.i = i; }
    public override string ToString()
        {
        return string.Format("{0} - {1}", i, s);
        }
    }
class reftype
    {
    public int i;
    public string s;
    public reftype(int i, string s) { this.s = s; this.i = i; }
    public override string ToString()
        {
        return string.Format("{0} - {1}", i, s);
        }
    }

private void frmMain_Load(object sender, EventArgs e)
    {
    valtype vt = new valtype(27, "val");
    valtype vt2 = vt;
    vt.i = 999;
    vt.s = "Changed!";
    Console.WriteLine(vt);
    Console.WriteLine(vt2);
    reftype rt = new reftype(17, "ref");
    reftype rt2 = rt;
    rt.i = 666;
    rt.s = "Changed as well!";
    Console.WriteLine(rt);
    Console.WriteLine(rt2);
    }


如果运行此代码,(我建议您这样做),您将得到:


If you run this code, (and I suggest you do) you will get:

999 - Changed!
27 - val
666 - Changed as well!
666 - Changed as well!

我不是在暗示这是好的代码-那里有一些非常糟糕的做法-但这说明了我的意思.

I''m not suggesting this is good code - it has some very bad practices in there - but it shows what I mean.


这篇关于值类型和引用类型之间有什么区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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