C#中的方法参数分为四种:
class Class1
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
int i = 1;
int j = 2;
Swap(i,j);
//因为是按值传递参数,所以没有达到交换目的。输出i=1,j=2.
Console.WriteLine("i={0},j={1}",i,j);
Console.ReadLine();
}
//交换值
static void Swap(int i,int j)
{
int intTemp = i;
i = j;
j = intTemp;
}
}
class Class1
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
int[] i = new int[3]{1,2,3};
int[] j = new int[4]{-1,-2,-3,0};
Swap(i,j);
//因为是按值传递参数(即使是引用类型),所以没有达到交换目的。输出i的第一个元素=1,j的第一个元素=-1
Console.WriteLine("i的第一个元素={0},j的第一个元素={1}",i[0],j[0]);
Console.ReadLine();
}
//交换值
static void Swap(int[] i,int[] j)
{
int[] intTemp = i;
i = j;
j = intTemp;
}
}
class Class1
{
static void Main(string[] args)
{
int[] i = new int[3]{1,2,3};
int[] j = new int[4]{-1,-2,-3,0};
Swap(ref i,ref j);
//输出i的第一个元素=1,j的第一个元素=-1
Console.WriteLine("i的第一个元素={0},j的第一个元素={1}",i[0],j[0]);
Console.ReadLine();
}
//交换值
static void Swap(ref int[] i,ref int[] j)
{
int[] intTemp = i;
i = j;
j = intTemp;
}
}
class Class1
{
string s = "";
static void Main(string[] args)
{
Class1 class1 = new Class1();
class1.Test2();
}
//交换值
void Test(ref string a,ref string b)
{
s = "s";
a = "a";
b = "b";
}
void Test2()
{
Test(ref s,ref s);
//输出s="b",因为s和a、b实际上都指向同一个内存地址
Console.WriteLine("s={0}",s);
Console.ReadLine();
}
}
值参数:不带修饰符;
引用型参数:用ref修饰
数组型参数:用params修饰
输出参数:用out修饰
一、值参数
在利用值向方法传递参数时,编译程序会给实参做一份拷贝,并把此拷贝的值传递给方法,被调用的方法内部的处理不会改变内存中实参的值。比如以下的程序:
class Class1
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
int i = 1;
int j = 2;
Swap(i,j);
//因为是按值传递参数,所以没有达到交换目的。输出i=1,j=2.
Console.WriteLine("i={0},j={1}",i,j);
Console.ReadLine();
}
//交换值
static void Swap(int i,int j)
{
int intTemp = i;
i = j;
j = intTemp;
}
}
而且需要注意的是,即使是对于参数是引用类型的变量,如果也是按值传递参数,则同样不会改变实参的值,比如下面代码:
class Class1
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
int[] i = new int[3]{1,2,3};
int[] j = new int[4]{-1,-2,-3,0};
Swap(i,j);
//因为是按值传递参数(即使是引用类型),所以没有达到交换目的。输出i的第一个元素=1,j的第一个元素=-1
Console.WriteLine("i的第一个元素={0},j的第一个元素={1}",i[0],j[0]);
Console.ReadLine();
}
//交换值
static void Swap(int[] i,int[] j)
{
int[] intTemp = i;
i = j;
j = intTemp;
}
}
(问题:如果是传一个数组到方法内部,则其值又会改变,这似乎有点矛盾)
二、引用型参数
使用ref关键字修饰。让一个值类型的参数按引用传递。ref关键字使用一个方法不再受只能返回一个值的限制(另一种方式是使用out关键字),而且,ref关键字便得更新值类型的变量成为可能,同时,也使参数可以传入方法,也可以从方法中传出。引用型参数必须要先初始化才可以使用。
当利用引用型的参数向方法传递形参时,编译程序并不开辟新的内存区域,而是把实参在内存中的地址传递过去,从而会改变实参的值。如以下代码:
class Class1
{
static void Main(string[] args)
{
int[] i = new int[3]{1,2,3};
int[] j = new int[4]{-1,-2,-3,0};
Swap(ref i,ref j);
//输出i的第一个元素=1,j的第一个元素=-1
Console.WriteLine("i的第一个元素={0},j的第一个元素={1}",i[0],j[0]);
Console.ReadLine();
}
//交换值
static void Swap(ref int[] i,ref int[] j)
{
int[] intTemp = i;
i = j;
j = intTemp;
}
}
对于按引用传参来说,会导致多个变量指向同一个地址,比如以下代码:
class Class1
{
string s = "";
static void Main(string[] args)
{
Class1 class1 = new Class1();
class1.Test2();
}
//交换值
void Test(ref string a,ref string b)
{
s = "s";
a = "a";
b = "b";
}
void Test2()
{
Test(ref s,ref s);
//输出s="b",因为s和a、b实际上都指向同一个内存地址
Console.WriteLine("s={0}",s);
Console.ReadLine();
}
}
三、数组型参数
用params修饰。只能位于参数表的最后一个参数,且只能是一维数组,比如:string[]和string[][],而string[,]则不允许。此外,数组型参数不允许有ref或out修饰符。