值与引用参数ref
声明时不带修饰符的形参是值形参,初始值来自该方法调用所提供的相应实参。
static void Main(string[] args)
{
int i = 100;
Test(i);
Console.WriteLine(i);//i还是100,值传递没有被改变
int[] a = new int[] { 1, 2 };
Test2(a);
Console.WriteLine(a[0]+" "+a[1]);//88 99这是引用传递,值被改变了,传进去的只是a的地址
int t = 111;
Test3(ref t);
Console.WriteLine(t);//222,实参与形参都加关键字ref,就变成了引用传递,传的是值的地址
}
static void Test(int i)
{
i = 300;
}
static void Test2(int[] a)
{
a[0] = 88;
a[1] = 99;
}
static void Test3(ref int t)
{
t = 222;
}
输出参数out
获得除了返回值以外的额外输出。和传进来的实参指向同一个内存的位置,是引用传递。
这样,一个函数可以变相的有多个返回值。
和ref一样,语义上不一样,ref是为了改变,out是为了输出
static void Main(string[] args)
{
int a = 100;
int b = 0;
bool bo = Test(a,out b);
Console.WriteLine(b);//200
//声明一些空变量用来接收out参数的返回值
int aa = 0;
string bb = "";
double cc = 0;
bool dd = Test(out aa, out bb, out cc);
//变相获得了4个返回值
Console.WriteLine(aa);
Console.WriteLine(bb);
Console.WriteLine(cc);
Console.WriteLine(dd);
}
static bool Test(int i, out int b)
{
//方法体里面必须为out参数赋值
b = i * 2;
return true;
}
static bool Test(out int aa,out string bb,out double cc)
{
aa = 1234;
bb = "假设aa,bb,cc都是经过了不止这么弱智的计算";
cc = 123.456;
return true;
}
数组参数params
必须是形参列表的最后一个,由params修饰
static void Main(string[] args)
{
int sum = getSum(1, 2, 3, 4, 5, 6, 7, 8, 9);
Console.WriteLine(sum);
}
static int getSum(params int[] i)
{
int sum = 0;
foreach(int ii in i)
{
sum += ii;
}
return sum;
}
具名参数
- 可以提高可读性
- 参数顺序不受参数列表约束 ```csharp static void Main(string[] args) { Test(“张三”, 12);//不具名 Test( age: 21,name: “李四”);//具名 } static void Test(string name,int age) {
}
<a name="axxhz"></a>
# 可选参数
```csharp
static void Main(string[] args)
{
Test("张三");//age在声明时有了默认初始值,可以不填
}
static void Test(string name,int age = 12)
{
}
扩展方法this
给一个类型对象添加一个方法,格外拓展。
class Program
{
static void Main(string[] args)
{
int a = 100;//目前a没有我们想要的方法,我们想要给他加一个方法
//调用时 . 前面的 a就是第一个参数,括号里面写出了被this修饰的其他参数
Console.WriteLine(a.setInt(14));//1400
}
}
//创建一个静态的类,名字约定俗成,想要扩展的类名+Extension
static class IntExtension
{
//静态方法,第一个加上this修饰,a就是要加方法的那个东西,后面的就是正常参数
public static int setInt(this int a,int b)
{
return a * b;
}
}