C#形参和实参、引用类型和值类型使用时的一个注意点。

这是早上群里讨论的例子。

 1 static void main(string [] arg){
 2
 3 var p1=new Person{Name="张三"};
 4 var p2=new Person{Name="李四"};  int i=0;
 5 A1(p1,i);
 6 A2(p2,ref i);
 7 Console.WriteLine(p1.Name+"----"+i);//输出张三-----0
 8 Console.WriteLine(p2.Name+"----"+i);//输出孙六-----1  9

 } 10 

11 void A1(string ppp,int i){
      i++;
12 ppp=new Person{Name="王五"};
13 }
14 void A2(string ppp,ref int i){      i++;
15 ppp.Name="孙六";
16 }

80%的老程序员在输出p1.Name时都错了,都以为是王五。一开始我也不理解。A1中引用类型的ppp改变了,为什么输出的还是“张三”?后来搜索资料明白了关键因素——【形参和实参是两个不同的变量!】

形参就是方法声明时的参数。如void A1(string ppp)的ppp。实参就是调用方法时传递的参数。如A1(p1)的p1。

百度知道里一位大牛的总结:
【函数调用中发生的数据传送是单向的。 即只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。 因此在函数调用过程中,形参的值发生改变,而实参中的值不会变化。】
因为A1方法里,ppp=new Person{Name="王五"};的操作把形参ppp地址改变了,不在是p1的引用地址。所以导致无法对实参p1产生影响。
对比A2。ppp和p2的引用地址始终一样。所以对p1一直有影响。

时间: 2024-08-02 01:08:57

C#形参和实参、引用类型和值类型使用时的一个注意点。的相关文章

CLR via C#深解笔记三 - 基元类型、引用类型和值类型 | 类型和成员基础 | 常量和字段

编程语言的基元类型 某些数据类型如此常用,以至于许多编译器允许代码以简化的语法来操纵它们. System.Int32 a = new System.Int32();  // a = 0 a = 1; 等价于: int a = 1; 这种语法不仅增强了代码的可读性,其生成的IL代码与使用System.Int32时生成的IL代码是完全一致的. 编译器直接支持的数据类型称为基元类型(primitive type).基元类型直接映射到Framework类库(FCL)中存在的类型.如C#中,int直接映射

引用类型和值类型

CLR支持两种类型:引用类型和值类型. 虽然FCL中大多数都是引用类型,但开发人员用的最多的还是值类型.引用类型总是在托管堆上分配的,C#的new操作符会返回对象的内存地址——也就是指向对象数据的内存地址. 使用引用类型必须注意到一些性能问题,首先考虑一下事实: 1)内存必须从托管堆上分配. 2)对上分配的每个对象都有一些额外的成员(比如前面提到过得"类型对象指针"和"同步块索引"),这些成员必须初始化. 3)对象中的其他字节(为字段而设)总是设为零. 4)从托管堆

第五章 基元类型、引用类型 和 值类型

1. 概述 本章讨论MS.NET Framework开发人员经常接触到的各种类型. 2. 名词解释 ① 基元类型:编译器直接支持的数据类型. ② 装箱:将一个值类型转换成一个引用类型. ③ 拆箱:获取已装箱的对象中的各个字段的地址. 3. 主要内容 3.1 编程语言的基元类型 作者建议开发人员开发中使用FCL类型名称,不要使用简化的基元类型名称.原因如下: ① 简化名称的映射容易混淆. ② 不同的编程语言,规则不一. ③ 影响代码的阅读. ④ 时间长了容易忘掉多语言环境的支持. checked

第5章 基元类型、引用类型和值类型

5.1编程语言的基元类型 编译器(Compiler)直接支持的数据类型称为基元类型(primitive type). 我希望编译器根本不要提供基元类型名称,强制开发人员使用FCL(Framework类库)类型名称: 许多开发人员都困惑于到底应该使用string还是String.由于C#的string直接映射到System.String,所以两者是没有区别的.int始终映射到System.Int32,所以不管在什么操作系统上运行,代表的都是32位整数. 5.2引用类型和值类型 虽然FCL中大多数类

[C++程序设计]有关形参与实参,及返回值说明

有关形参与实参的说明:(1) 在定义函数时指定的形参,在未出现函数调用 时,它们并不占内存中的存储单元,因此称它们是 形式参数或虚拟参数,表示它们并不是实际存在的数据,只有在发生函数调用时,函数max中的形参才被分配内存单元,以便接收从实参传来的数据. 在调用结束后,形参所占的内存单元也被释放 (4) 实参与形参的类型应相同或赋值兼容.如果实参为整型而形参为实型,或者相反,则按不同类型数值的赋值规则进行转换.例如实参a的值为3.5,而形参x为整型,则将3.5转换成整数3,然后 送到形参b.字符型

[CLR via C#]引用类型和值类型

一.引用类型与值类型的区别 CLR支持两种类型:引用类型和值类型.引用类型总是从托管堆上分配的,C#的new操作符会返回对象的内存地址.使用引用类型时,必须注意到一些性能问题. 1)内存必须从托管堆上分配. 2)堆上分配的每个对象都有一些额外的成员(类型对象指针和同步索引块),这些成员必须初始化. 3)对象中的其他字节(为字段而设)总是设为零. 4)从托管城市化上分配一个对象时,可能强制执行一次垃圾收集操作. 为了提升简单的.常用的类型的性能,CLR提供了名为"值类型"的轻量级类型.值

【转】c#引用类型与值类型的区别大盘点

解析:CLR支持两种类型:值类型和引用类型.用Jeffrey Richter(<CLR via C#>作者)的话来说,“不理解引用类型和值类型区别的程序员将会把代码引入诡异的陷阱和诸多性能问题”.这就要求我们正确理解和使用值类型和引用类型. 值类型包括C#的基本类型(用关键字int.char.float等来声明),结构(用struct关键字声明的类型),枚举(用enum关键字声明的类型):而引用类型包括类(用class关键字声明的类型)和委托(用delegate关键字声明的特殊类).C#中的每

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

1***.C#中有两种类型: 值类型和引用类型: 值类型的变量直接包含他们的数据,而引用类型的变量存储 引用类型存储对他们的数据的引用,后者称为对象: 简单说:值类型直接存储其值,引用类型存储对值得引用.引用类型分为引用和引用的对象. 2***. 值类型:简单类型.枚举.结构 引用类型: 类类型.接口类型.数组类型和委托类型 3***.值类型与引用类型的内存存储 单纯的说值类型存储在栈上,引用类型存储在托管堆上是不对的. 4***.区别: 1. 托管堆: 同步块和方法表, x,y,托管堆上的需要

12-12面向对象--引用类型与值类型、命名空间与类库

五.引用类型与值类型 .NET将变量的类型分为值类型与引用类型.例如int和float之类的变量属于值类型,而“类“类型的变量属于引用类型. 值类型与引用类型的变量在使用上是有区别的. 值类型的变量在一定义之后就可以马上使用. 引用类型的变量定义之后,还必须用new关键字创建对象后才可以使用. 如上图,创建两个新的对象时,直接比较两个对象是否相等,返回的bool值为false.因为两个对象都是新开辟的一个空间变量,彼此没有任何关系,所有是不相等的. 如图2:1)创建的第一个新的对象ss1,给ss