ref和out的区别
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace one
{
class Program
{
static void Main(string[] args)
{
int a = 10;
Refa(ref a);
Console.WriteLine(a);//11
Outa(out a);
Console.WriteLine(a);//4
Console.Read();
}
static void Refa(ref int a)
{
a++;
}
static void Outa(out int a)
{
a = 5;
a--;
}
}
}
上面的代码中,原本的a是10,运行Refa(ref a)之后,外部的a就变成了11。如果去掉ref关键字后,重新运行一次,a的值还是原来的10,所以ref关键字可以改变外部的值。
在函数中,out关键字修饰的a必须在函数体中进行赋值,即a=5或者a=其他值,这是必须要有的,不然会报错,然后函数体内的方法执行完后,如果函数体内的a值改变了,那么外界的a的值也跟着改变了。
所以out和ref都可以在函数体中进行操作而改变外部的值,但是out必须要在函数体中进行赋值,而ref可以在函数体中赋值,也可以不赋值。
params关键字
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace one
{
class Program
{
static void Main(string[] args)
{
string[] aaa = { "hello", "world", "ddd" };
Fn(aaa);//分别输出了hello world ddd
Console.Read();
}
static void Fn(params string[] list)
{
foreach (var a in list)
{
Console.WriteLine(a);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace one
{
class Program
{
static void Main(string[] args)
{
string[] aaa = { "hello", "world", "ddd" };
Fn("hello", "world", "ddd");//分别输出了hello world ddd
Console.Read();
}
static void Fn(params string[] list)
{
foreach (var a in list)
{
Console.WriteLine(a);
}
}
}
}
这两段代码输出的内容是一样的,作用也是一样的。params 是C#的关键字, params主要是在声明方法时参数类型或者个数不确定时使用,可变的方法参数,也称数组型参数,适合于方法的参数个数不知的情况,用于传递大量的数组集合参数。在参数中,可以有多个参数,但是params参数必须是形参表中最后一个参数,可以和ref、out修饰的一起使用,但是params修饰的必须是最后一个。
yield关键字
yield关键字的作用是将当前集合中的元素立即返回,只要没有yield break,方法还是会继续执行循环到迭代结束。
1.返回元素用yield return;(一次一个的返回)
2.结束返回用yield break;(终止迭代)
3.返回类型必须为 IEnumerable、IEnumerable、IEnumerator 或 IEnumerator。
4.参数前不能使用ref和out关键字
5.匿名方法中 不能使用yield
6.unsef中不能使用
7.不能将 yield return 语句置于 try-catch 块中。 可将 yield return 语句置于 try-finally 语句的 try 块中。yield break 语句可以位于 try 块或 catch 块,但不能位于 finally 块。
代码如下:
using static System.Console;
using System.Collections.Generic;
class Program
{
//一个返回类型为IEnumerable<int>,其中包含三个yield return
public static IEnumerable<int> enumerableFuc()
{
yield return 1;
yield return 2;
yield return 3;
}
static void Main(string[] args)
{
//通过foreach循环迭代此函数
foreach(int item in enumerableFuc())
{
WriteLine(item);
}
ReadKey();
}
}
输出结果:
1
2
3
yield break具有终止迭代的作用,跟break终止循环差不多。
代码如下:
using static System.Console;
using System.Collections.Generic;
class Program
{
//一个返回类型为IEnumerable<int>,其中包含三个yield return
public static IEnumerable<int> enumerableFuc()
{
yield return 1;
yield return 2;
yield break;//终止迭代,后面的代码不执行了。
yield return 3;
}
static void Main(string[] args)
{
//通过foreach循环迭代此函数
foreach(int item in enumerableFuc())
{
WriteLine(item);
}
ReadKey();
}
}
输出结果:
1
2