您的位置:首页 > 编程语言 > C#

C# 值传递与引用传递的区别

2015-12-22 11:54 447 查看


一、传递值类型参数


1、通过值传递值类型

当实参当作值来传递时,就产生的一个副本,也就是值不发生变化。

class MyTest
{
static void Main(string[] args)
{
int number=10;
ModifyValue(number);
Console.WriteLine("number={0}",number);
}

static void ModifyValue(int num)
{
num++;
Console.WriteLine("num={0}",num);
}
}

程序运行结果为:num=11,number=10;

即number的值不会受num影响,给num赋一个新值并不会改变number的内容,因为num和number存在于内存中不同的位置。

2.通过引用传递值类型

(1)使用ref关键字时,表示是用引用的方式传递参数。实参和形参引用的都是同一个对象,改变其中一个的引用值,另一个也会改变。

class MyTest
{
static void Main(string[] args)
{
int number=20;
ModifyValue(ref number);
Console.WriteLine("number={0}",number);
}

static void ModifyValue(ref int num)
{
num++;
Console.WriteLine("num={0}",num);
}
}
程序运行结果为:num=21,number=21; 即number的值会受num影响,随之值发生改变。

class MyTest
{
static void Main(string[] args)
{
int number=15;
ModifyValue(ref number);
Console.WriteLine("number={0}",number);
}

static void ModifyValue(ref int num)
{
num=100;
num++;
Console.WriteLine("num={0}",num);
}
}


程序运行结果为:num=101,number=101;

注意:
ref修饰符在写函数和调用函数时都一定要出现。

3.
交换值类型


/// <summary>
/// 交换位置
/// </summary>
public static void InputData()
{
int num1 = 15, num2 = 10;   // 两个数字
Console.WriteLine("交换前两个数的值分别为:{0}和{1}", num1, num2);
// Swap(num1, num2);   // 交换两个数的值(值传递:值的副本(值不发生变化))
Swap(ref num1, ref num2); //ref引用传递:传的地址(值发生改变)
Console.WriteLine("交换后两个数的值分别为:{0}和{1}", num1, num2);
}

/// <summary>
/// 交换的方法
/// </summary>
/// <param name="num1"></param>
/// <param name="num2"></param>
private static void Swap(ref int num1, ref int num2)
//   private static void Swap(int num1,int num2)
{
int temp = num1;
num1 = num2;
num2 = temp;
}


out修饰符与ref修饰符非常相似,除了以下两点为:

一、在调用函数时不需要赋值。

二、在函数退出前必须赋值。

out修饰符通常用于需要从方法中获取多个返回值的时候
static void SubStringName(string name, out string firstName, out string lastName)
{
int i = name.LastIndexOf(' ');
firstName = name.Substring(0, i); //截取姓
lastName = name.Substring(i + 1); //截取名
}
static void Main(){
string name = "Mrs JOHN";
string a, b;  //输出变量
SubStringName(name, out a, out b);
Console.WriteLine(a);
Console.WriteLine(b);

Console.ReadLine();
}


[b]二、传递引用类型参数[/b]

引用类型的变量不直接包含其数据;它包含的是对其数据的引用。当通过值传递引用类型的参数时,有可能更改引用所指向的数据,如某类成员的值。但是无法更改引用本身的值;也就是说,不能使用相同的引用为新类分配内存并使之在块外保持。若要这样做,应使用 ref 或 out 关键字传递参数。


1、通过值传递引用类型

数组 arr 为引用类型,在未使用 ref 参数的情况下传递给方法。
在此情况下,将向方法传递指向 arr 的引用的一个副本。输出显示方法有可能更改数组元素的内容
static void Change(int[] my)
{
my[0] = 888;  // 赋值
my = new int[5] { -3, -1, -2, -3, -4 };   // 重新赋值.
System.Console.WriteLine("my: {0}", my[0]);  //-3
}
static void Main(){
int[] arr = { 10, 40, 50 };
System.Console.WriteLine("arr: {0}", arr[0]);  //10

Change(arr);  //调用方法
System.Console.WriteLine("changeMethod arr: {0}", arr[0]);  //888

Console.ReadLine();
}

在这种情况下,从 10改为 888。但是,在 Change 方法内使用 new 运算符来分配新的内存部分,将使变量
my引用新的数组。因此,这之后的任何更改都不会影响原始数组 arr(它是在 Main 内创建的)。

2.通过引用传递引用类型

使用 ref 关键字,方法内发生的任何更改都会影响调用程序中的原始变量.

static void Change(ref int[] my)
{
my[0] = 888;  // 赋值
my = new int[5] { -3, -1, -2, -3, -4 };   // 重新赋值.
System.Console.WriteLine("my: {0}", my[0]);  //-3
}
static void Main(){
int[] arr = { 10, 40, 50 };
System.Console.WriteLine("arr: {0}", arr[0]);  //10

Change(ref arr);
System.Console.WriteLine("changeMethod arr: {0}", arr[0]);  //-3  值发生变化

Console.ReadLine();
}

实际上,使用 new 运算符对原始数组进行了重新分配。因此,调用 Change 方法后,对 arr 的任何引用都将指向 Change 方法中创建的五个元素的数组。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: