`

关于C#值类型,引用类型,值传递,引用传递

 
阅读更多
http://www.cnblogs.com/greatandforever/archive/2008/07/08/1238180.html

关于C#值类型,引用类型,值传递,引用传递


说到参数传递,必须得弄清值类型和引用类型:
(为了容易表达,我暂且命名存放在堆中的内容为堆中对象,存放在栈上的内容为栈中对象。)
值类型存放在栈中,直接访问。如果有:int a=0;int b=a;就产生了两个栈中对象。
引用类型需要在堆中显式分配,且不能直接访问,需要在栈中分配一个栈中对象(C++叫指针,C#叫引用)指向其堆中对象。
如果:
StringBuilder strb = new StringBuilder();
StringBuilder strb2 = strb;
则在堆中只有一个堆中对象,只是栈中有两个栈中对象指向堆中对象。
可以看出:每个变量都是一个栈中对象。不管是值类型还是引用类型,只是值类型的栈中对象就是其内容,而引用类型的栈中对象只是一个指向堆中对象的地址。

判断是值类型还是引用类型:

int a1 = 10;
StringBuilder strb1 = new StringBuilder("ABC");

int a2 = a1;
StringBuilder strb2 = strb1;

bool bl1 = object.ReferenceEquals(a1,a2);   //false为值类型(因为值类型要装箱)
bool bl2 = object.ReferenceEquals(strb1,strb2);   //true为引用类型




参数传递分值传递和引用传递两种。
通常,在没有显式指出ref和out时都是值传递。

值传递:传的是对象的值拷贝。(即函数内参数对象是调用时传递对象的栈中对象的拷贝。)
引用传递:传的是栈中对象的地址。(即函数内参数对象与调用时传递对象完全是同一栈中对象。)
现在用例子来说明传值跟传地址的不同:

private void button2_Click(object sender, System.EventArgs e)
{
  StringBuilder strb1 = new StringBuilder();
  StringBuilder strb2 = new StringBuilder();
  Test1(strb1);
  Test2(ref strb2);
  string str1 = strb1.ToString(); //str1值:"A"
  string str2 = strb2.ToString(); //str2值:"BC"
}

void Test1(StringBuilder strb)
{
  //strb和strb1是两个栈中对象,但指向相同的地址,这个操作是改变堆中对象
  strb.Append("A");

  //这里将strb指向一个新的堆中对象,所以后面的操作与strb1指向的栈中对象无关
  strb = new StringBuilder("B");
  strb.Append("C");
}

void Test2(ref StringBuilder strb)
{
  //这里的strb和strb2是同一个栈中对象,所以改变strb的值使其指向另一个对象也等于改变strb2
  strb = new StringBuilder("B");
  strb.Append("C");
}

分享到:
评论

相关推荐

    C#中引用类型和值类型的区别

    在C#编程语言中,类型系统是其核心组成部分,它主要分为两大类:引用类型和值类型。这两种类型的差异在程序设计与优化中扮演着关键角色,了解它们的区别对于提高代码质量和性能至关重要。 ### 引用类型 引用类型在...

    C#基础知识 值类型、引用类型

    本文将深入探讨C#中的核心概念:值类型和引用类型。这两种类型在内存管理和数据处理上有着显著的区别,理解它们对于编写高效且无错的代码至关重要。 值类型(Value Types)包括基本类型如整型(int)、浮点型...

    C#笔记值传递和引用传递

    虽然在其他语言中可能被视为值类型,但在C#中,string是引用类型,这意味着字符串对象在内存堆中存储,通过引用传递。 关于内存管理,值类型存储在栈中,栈的内存由编译器自动管理,当变量的作用域结束时,栈上的...

    C#引用类型的赋值 类的赋值

    C#中引用类型的赋值操作实际上只是传递了指向对象的引用,而不是复制整个对象本身。这意味着在处理大型对象时,引用类型的赋值操作比值类型的赋值更加高效。然而,在某些场景下需要注意这种特性可能导致的副作用,...

    C#值类型和引用类型及参数传递[收集].pdf

    C#值类型和引用类型及参数传递[收集].pdf

    理解 C#值类型与引用类型.docx

    在C#编程中,理解值类型和引用类型是至关重要的,因为它们决定了变量如何存储、复制和传递。本文将深入探讨这两个概念,并提供实用的建议,以帮助开发人员避免潜在的错误和性能问题。 1. **通用类型系统** C#的...

    LabVIEW中引用的概念及在VI间传递值

    本文将深入探讨LabVIEW中的引用概念以及如何在虚拟仪器(VI)之间通过引用传递值。 引用在LabVIEW中的基本理解是,它是一个指向内存中特定数据位置的指针。当你创建一个引用时,你不是创建数据的副本,而是创建了一...

    训练师脚本:《使用C#中的枚举、结构、值类型和引用类型

    ### 使用C#中的枚举、结构、值类型和引用类型 #### 枚举(Enum) **定义**: 枚举是一种特殊的类,它定义了一组固定的命名常量,通常用于表示一系列预定义的值。 **语法**: ```csharp [访问修饰符] enum 枚举名 { ...

    C#的几种数据传递类型

    C#支持两种主要的数据传递方式:值传递(Passing by Value)和引用传递(Passing by Reference)。此外,还有输出参数(Out Parameters)和ref参数,它们在一定程度上提供了类似于引用传递的功能。下面我们将详细...

    理解C# String类型:特殊的引用类型

    在 C# 中,String 类型的传递可以是值传递,也可以是引用传递。当使用值传递时,实际上是在函数体内对 str 进行修改之前,与函数外部的变量指向同一块内存,是“引用”传递,但在函数体内对 str 修改后,就会触发对...

    2.1.4 C++和C#数据传递 -class类型传递

    C++支持两种主要的数据传递方式:按值传递(Pass by Value)和按引用传递(Pass by Reference)。当类对象作为参数按值传递时,实际上是创建了该对象的一个副本,对副本进行的操作不会影响原始对象。这在一定程度上...

    2.1.1 C++和C#数据传递 -常用类型数组和List类型传递

    总的来说,C++和C#在数据传递上都支持值传递和引用传递,但C++需要明确选择引用或指针来实现引用传递,而C#总是进行引用传递。数组和列表在两者的处理方式上有共同之处,但C++的`std::vector`更强调内存管理和性能...

    C#中的值传递和引用传递详细解析

    在C#编程语言中,参数传递有两种主要方式:值传递和引用传递。这两种方式决定了函数或方法如何处理传递给它们的变量。 1. 值传递:这是C#中最常见的参数传递方式。当一个值类型(如int、bool或结构)的变量作为参数...

    c#基础系列之值类型和引用类型的深入理解

    当传递引用类型变量时,传递的实际上是内存地址的引用,而不是数据本身的副本。 引用类型的变量可以在未初始化时赋值为null,这表示该变量当前没有指向任何有效的数据实例,从而可能会引发异常。正是由于引用类型的...

    C#编写的一个高级语言程序——值传递2

    它涉及到值类型和引用类型的区别,以及如何通过`ref`和`out`关键字实现按引用传递。在日常编程中,合理选择参数传递方式,可以优化性能,避免不必要的数据复制,同时确保代码的清晰性和可维护性。

    值类型与引用类型(.html)

    在C#编程语言中,值类型和引用类型是两种基本的数据类型,它们在内存管理和数据存储方式上有着显著的区别,这对于理解和优化代码性能至关重要。本文将深入探讨这两种类型的特性和应用场景。 1. 值类型(Value Types...

    C#一个类型(值或引用类型)的实例在内存中的字节.rar

    这意味着即使在多个地方持有相同的引用,对对象的修改都是共享的,即按引用传递。 3. 垃圾回收(Garbage Collection, GC): - 在C#中,垃圾回收机制自动管理堆内存,识别并释放不再使用的对象。当一个引用类型...

    winform 值类型引用类型比较源码

    1. 如何通过值类型和引用类型来传递数据,比如在控件间传递数值或者对象。 2. 深拷贝和浅拷贝的概念:值类型变量的复制是深拷贝,而引用类型变量的赋值是浅拷贝。 3. 性能比较:在大量数据操作时,值类型的效率可能...

    C#调用C++ Dll关于结构体数组引用的传递及解析使用的展示代码

    ### C#调用C++ DLL:结构体数组引用的传递及解析使用详解 #### 引言 在跨语言编程环境中,经常会遇到不同编程语言之间进行交互的需求。C#与C++之间的互操作就是一个典型场景。当C#需要调用C++开发的动态链接库...

    c# 参数传递,参数调用

    除了值传递和引用传递,C# 还有一种特殊的参数传递方式——按装箱值类型传递(boxing for value types)。当值类型(如 int 或 struct)被传递给一个接受对象类型的参数时,会自动进行装箱操作,将值类型转换为对应...

Global site tag (gtag.js) - Google Analytics