我正在阅读Eric的博客:关于价值类型的真理
在这篇文章中,他提到开头有三种价值:
因此,在下面的示例中:
int i = 10;
string s = "Hello"首先是值类型的实例,其次是引用类型的实例。那么,第三种类型是什么,引用,我们如何获得它呢?
发布于 2014-03-26 19:57:21
那么,第三种类型是什么,引用,我们如何获得它呢?
变量s是一个保存引用值的变量。此值是对内存中字符串(值为"Hello")的引用。
为了更清楚地说明这一点,请说:
string s1 = "Hello";
string s2 = s1;在这种情况下,s1和s2都是对同一个引用类型实例(字符串)的引用。这里只涉及一个实际的字符串实例(引用类型),但是有两个对该实例的引用。
发布于 2014-03-26 19:57:18
引用类型的字段和变量(如您的s )是对堆上存在的引用类型实例的引用。
您从不直接使用引用类型的实例,而是通过引用使用它。
发布于 2014-03-26 20:30:53
引用不是真正的“第三种类型”。它实际上是一个指针,它引用了一个对象的具体实例。看一下这个例子:
class MyClass
{
public string Str { get; set; }
}
class Program
{
static void Main(string[] args)
{
int a = 1;
int b = 2;
int c = 3;
var myObj = new MyClass
{
Str = "Whatever"
};
Console.WriteLine("{0};\t{1};\t{2};\t{3}", a, b, c, myObj.Str);
MyFunction(a, ref b, out c, myObj);
Console.WriteLine("{0};\t{1};\t{2};\t{3}", a, b, c, myObj.Str);
Console.ReadLine();
}
static void MyFunction(int justValue, ref int refInt, out int outInt, MyClass obj)
{
obj.Str = "Hello";
justValue = 101;
refInt = 102;
outInt = 103; // similar to refInt, but you MUST set the value of the parameter if it's uses 'out' keyword
}
}该程序的输出是:
1; 2; 3; Whatever
1; 102; 103; Hello关注MyFunction:
我们传递的第一个参数是一个简单的int,它是一个值类型。默认情况下,当作为参数传递时会克隆值类型(正在创建一个新实例)。这就是为什么'a‘的值没有变化。
您可以通过在参数中添加'ref‘或'out’关键字来更改此行为。在这种情况下,您实际上传递了对int实例的引用。在MyFunction中,该实例的值正在被重写。在这里,您可以阅读“移出”、“引用”和“输出”。
最后一个例子是MyClass的对象。所有类都是引用类型,这就是为什么您总是将它们作为引用传递(不需要特殊的关键字)。
您可以将引用视为计算机内存中的地址。该地址上的字节构成您的对象。如果将其作为值传递,则取出这些字节并将其传递给函数。如果将其作为引用传递,则只传递地址。在被调用的函数中,您可以从该地址读取字节或将其写入该地址。每次更改都会影响调用函数变量,因为它们指向计算机内存中完全相同的字节。--这并不是.Net (它运行在虚拟机中)中发生的事情,但是我认为这个类比会帮助您理解这个概念。
我们为什么要用推荐信?有很多原因。其中之一是,通过值传递一个大对象将非常缓慢,需要对其进行克隆。当您传递对一个对象的引用时,无论该对象有多大,您只传递几个字节,其中包含内存中的“地址”。
此外,您的对象可能包含无法克隆的元素(如打开的套接字)。使用引用,您可以轻松地在函数之间传递这样的对象。
还值得一提的是,尽管sctructs看起来非常类似于类,但它们实际上是值类型,并且表现为值类型(当您将结构传递给函数时,实际上传递了一个克隆--一个新实例)。
https://stackoverflow.com/questions/22671708
复制相似问题