c# 值传递 引用传递
以前一直误以为引用类型,在作为参数传递时,都是引用传递(类似于值传递中的ref),也就是说,把引用类型的变量作为参数传递给方法,在方法中修改该参数,会改变这个变量的值,
后来通过一些事例发现,上面的认识是片面的,引用类型传递实际上也是属于值传递的,只是引用类型传递的是一个堆地址。
先来个例子吧:
- using System;
- public class test{
- public static void Main(){
- testClass a = new testClass();
- ChangeToNull(a);
- Console.WriteLine(string.Format("a不是null,它的属性值为:{0}", a.field));
- ChangeField(a);
- Console.WriteLine(string.Format("a的属性值为:{0}", a.field));
- ChangeToNull(ref a);
- Console.WriteLine(string.Format("a是不是null:{0}", (a == null)));
- }
- static void ChangeToNull(testClass b){
- b = null;
- if(b == null){
- Console.WriteLine("在ChangeToNull方法中,参数已经被修改成null了!");
- }
- }
- static void ChangeField(testClass b){
- b.field = 0;
- Console.WriteLine("在ChangeField方法中,参数的成员已经被修改成0了!");
- }
- static void ChangeToNull(ref testClass b){
- b = null;
- if(b == null){
- Console.WriteLine("在ChangeToNull使用ref的重载方法中,参数已经被修改成null了!");
- }
- }
- }
- class testClass{
- public int field;
- public testClass(){
- field = 123;
- }
- }
上面的代码,执行后的结果是:
在ChangeToNull方法中,参数已经被修改成null了!
a不是null,它的属性值为:123
在ChangeField方法中,参数的成员已经被修改成0了!
a的属性值为:0
在ChangeToNull使用ref的重载方法中,参数已经被修改成null了!
a是不是null:True
由此可见,引用类型作为参数时:
1、在修改变量本身时,结果类似于值传递,即不会改变传递前的变量的值
2、在修改变量的属性或字段时,才是引用传递,会影响到传递前的变量的值
3、参数使用了ref后,才是真正的引用传递,不管修改变量本身还是修改变量的属性或字段,都会影响到传递前的变量的值
究其原因,我们知道,值类型和引用类型,在运行时,它们存放的位置是不同的,值类型是存储在进程的栈上的
而引用类型是存储在进程堆(Heap)上的,在进程的栈上存储了这个引用类型在堆上的地址
而在调用方法时,是把栈上的参数的值复制一份传递给方法,所以值类型作为参数传递时,不会改变原变量值很明显
引用类型传递时,也是一样,把栈上的这个堆地址复制一份传递给方法,
所以在方法里修改这个复制的地址的值,当然不会改变原变量的值,
但是修改这个复制的地址所指向的堆里的内容,那原变量指向的地址的内容当然也跟着改变了。
如果参数加了ref,那传递的就是栈的地址的,此时不管是值类型还是引用类型,都会改变原变量的内容
综上所述,我们可以知道,引用类型作为参数传递,不能单纯的说它就是引用传递,如果直接这么认为,在开发中难免会犯错误的,深入的理解一下值类型和引用类型的传递,还是很有必要的。
c# 值传递 引用传递的更多相关文章
- 对象引用 方法传参 值传递 引用传递 易错点 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- C++之值传递&指针传递&引用传递详解
C++之值传递&指针传递&引用传递详解 目录 C++之值传递&指针传递&引用传递详解 1.函数基础 2.值传递 3.指针传递 4.引用传递 1.函数基础 一个函数由以下 ...
- php函数间的参数传递(值传递/引用传递)
php:函数间的参数传递 1.值传递 代码如下: <?php function exam($var1){ $var1++: echo "In Exam:" . $var1 . ...
- php 数组 类对象 值传递 引用传递 区别
一般的数据类型(int, float, bool)不做这方面的解说了 这里详细介绍一下数组和的类的对象作为参数进行值传递的区别 数组值传递 实例代码: <?php function main() ...
- 值传递 & 引用传递
以下程序的输出结果是? public class Example { String str = new String("good"); char[] ch = { 'a', 'b' ...
- 理解--->Java中的值传递&引用传递
转自:http://url.cn/5tL9F5D 值传递和引用传递 值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际 ...
- [转载]php 数组 类对象 值传递 引用传递 区别
一般的数据类型(int, float, bool)不做这方面的解说了 这里详细介绍一下数组和的类的对象作为参数进行值传递的区别 数组值传递 实例代码: <?php function main() ...
- Java小白进阶之值传递-引用传递
class ClassA{ int value;//成员变量 } public class TestClassA{ public static void main(String args[]){ in ...
- 3.GO-项目结构、包访问权限、闭包和值传递引用传递
3.1.goland中项目结构 (1)在goland中创建标准Go项目 (2)goland配置 创建项目Learn-Go file-settings-go-GOPATH-添加 在项目目录下创建src目 ...
随机推荐
- Network Wars
zoj2676:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1676 题意:给出一个带权无向图 ,每条边e有一个权 .求将点 ...
- CF_Lucky Sum
幸运数字的定义是这样:仅含4和7且不比n小的数为n的幸运数字. 输入范围l,r要求输出这个范围内的数字的幸运数字之和. 代码: #include<stdio.h> #define N 10 ...
- 带圆角的EditText
转载请注明出处:http://blog.csdn.net/krislight/article 1.定义一个Drawable <?xml version="1.0" encod ...
- 深入了解View实现原理以及自定义View详解
下面几篇文章对View的原理讲的非常详细. Android LayoutInflater原理分析,带你一步步深入了解View(一) Android视图绘制流程完全解析,带你一步步深入了解View(二) ...
- Python类的基础入门知识
http://www.codesky.net/article/201003/122860.html首先第一点,你会发现Python Class的定义中有一个括号,这是体现继承的地方. Java用ext ...
- statspack系列3
原文:http://jonathanlewis.wordpress.com/2006/12/27/analysing-statspack-3/ 作者:Jonathan Lewis 下面的例子中的结果并 ...
- C#实例:5个.net经典例子(窗体与界面设计)
实例001 带历史信息的菜单 实例说明 在开发图纸管理软件时,要求在菜单上记录用户最近打开的档案或图纸,以方便下次使用.如图1.1所示,单击“文件”菜单下的“打开文件”子菜单,打开需要查阅的图纸.下 ...
- 【转】win7 虚拟机virtualbox中ubuntu12.04安装samba实现文件共享
原文网址:http://blog.csdn.net/watkinsong/article/details/8878786 昨天心血来潮,又装了个虚拟机,然后安装了ubuntu12.04,为了实现在虚拟 ...
- 今天遇到的i++问题之记录
今天逛贴吧看到的,与自己预想的不同,于是在群里求解后方得知答案,遂记录之.代码来袭. function a(){ var i=1; i++; alert(i); } var c = a(); c(); ...
- HTML5 Canvas核心技术—图形、动画与游戏开发.pdf8
第6章 精灵 精灵(sprite),它是一种可以集成入动画之中的图像对象,赋予它们各种行为,精灵并非Canvas API的一部分,,但都是从它衍生而来 本章将会实现三种设计模式:策略模式(精灵与绘制器 ...