看看下面的程序
using System;
namespace AccessProject
{
class Program
{
public static void swap(int a,int b)
{
int temp = a;
a = b;
b = temp;
}
static void Main(string[] args)
{
int a = 10;
int b =20;
swap(a,b);
Console.WriteLine("a=" + a);
Console.WriteLine("b=" + b);
}
}
}
输出结果: a=10
b =20
这个例子里面,执行玩函数swap后,a,b的值都没有发生变化
接着看这个例子:
using System;
namespace AccessProject
{
public class A
{
internal int m;
public A(int m)
{
this.m = m;
}
public void fun(A a)
{
this.m = a.m;
}
}
class Program
{
static void Main(string[] args)
{
A a = new A(10);
A b = new A(20);
a.fun(b);
Console.WriteLine("a.m="+a.m);
}
}
}
输出结果是: a.m=20
这个例子里面,a执行完函数后,状态发生了改变
从这两个例子可以看出,c#的方法在处理参数的时候,和java一样,采用的是值调用的方法。对于值类型的数据(int ,float,double)等基本数据类型,参数传递过来后,形参和实参是两个不同的数据存储单元,因此,在函数里对形参进行处理后,并不影响实参。所以在函数处理完后,实参仍然是原来的值。而对于引用型的数据类型,如class,则实参传递进来后,尽管形参和实参是两个不同的存储单元,但是由于是引用类型,因此形参和实参都指向的是同一个地址。所以在函数里面对形参的处理实际上就是对实参的处理。所以函数返回后,实参的状态发生了变化。
我们最后再看这个例子:
using System;
namespace AccessProject
{
public class A
{
public void fun1(string s)
{
s = "HUST";
}
}
class Program
{
static void Main(string[] args)
{
A a = new A();
string s = "HUSTCS";
a.fun1(s);
Console.WriteLine("s="+s);
}
}
}
这里形参和实参在函数调用刚开始的时候都只向同一个存储地址,但是后面语句s="HUST"执行后,形参已经指向一个新的存储地址了,实际上形参和实参已经脱钩了,所以最后的输出结果为s=HUSTCS
这上面的处理机制和JAVA的机制是一致的,下面是C#的新增的部分
值调用的方式为形参和实参开辟了两个不同的存储区域,如果希望形参和共用一块存储空间怎么办,只要在形参前加上关键字 ref即可,值得注意的是,形参前面有ref关键字修饰的话,实参前也必须由关键字ref相对应
另外,C#里增加了新的带出参数这一部分,也就是说,C#允许某个参数将程序的运行结果带回来,这在一个函数需要返回多个值的时候特别有用处。