ref,out,int参数复习
ref
结构是值类型,按值传递。通过关键字ref,也可以通过引用传递结构。
public static void ChangeA(ref A a) {
a.X = 2; } //如果A是结构类型,就添加ref修饰符,修改ChangeA方法的声明,通过引用传递变量
在Main函授中执行,按照引用传递,所以结果是2。
A a1 = new A {X =1}; ChangeA(ref a1); Console.WriteLine(a1.X); //给方法参数应用了ref修饰符后,在调用方法时需要添加它。
使用ref后,也可以传递对引用的引用(在C++术语中,是一个指向指针的指针),它允许分配一个新对象。
public static void ChangeA(A a) { a.X = 2; a = new A {X = 3};//这一行在堆栈上创建了一个新对象,和一个对新对象的引用。Main()方法中使用的变量a1仍然引用值为1的旧对象。ChangeA方法结束后,没有引用堆栈上的新对象,可以回收它。所以这里的Main()方法里输出结果仍然是1. } //添加ref修饰符后,传递对引用的引用,允许分配新对象,此时Main()方法里,输出结果是3. public static void ChangeA(ref A a) { a.X = 2; a = new A {X = 3}; }
完整代码
using System; namespace refDemo { class Program { static void Main(string[] args) { //Console.WriteLine("Hello World!"); A a1 = new A{X = 1}; //ChangeA(ref a1); ChangeANotRef(ref a1); System.Console.WriteLine($"{a1.X.ToString()}"); } private static void ChangeA(ref A a) { a.X = 2; } private static void ChangeANotRef(ref A a) { a.X = 2; a = new A{X = 3}; } } struct A { public int X; } }
out
如果方法返回一个值,该方法通常声明返回类型,并返回结果。如果方法返回多个值,可能类型还不同,这有不同的选项去处理。一个选项是声明类和结构,把应该返回的所有信息都定义为该类型的成员。另一个选项是使用元组类型。第三个选项是使用out关键字。
if(int.TryParse(Console.ReadLine(),out int num)) { //to do; } //返回一个bool值,当用户输入的字符串可以转换为Int32时,返回true,反之为false.
若方法已明确定义返回类型,则也可以用关键字var代替int.
in
C#7.2向参数添加了in修饰符。out修饰符允许返回参数指定的值。in修饰符保证发送到方法中的数据不会更改(在传递值类型时)。
下面定义一个简单的可变结构体,再定义一个公共可变字段。
struct AValueType { public int Data; }
此时,使用in修饰符定义一个方法时,变量就不能更改了。试图更改可变字段Data,编译器会报错,不能为只读变量的成员分配值。in修饰符使参数设置为只读变量。
static void CantChange(in AValueType a) { //a.Data = 43;//does not compile - readonly variable Console.WriteLine(a.Data); }
使用in修饰符,不仅有助于确保不更改内存,编译器还可以创建更好的优化代码。与使用方法调用来复制值类型不同,编译器可以使用引用,从而减少所需内存并提高性能。
注:in修饰符主要用于值类型,也可以对引用类型使用它。in修饰符用于引用类型时,可以更改该引用类型变量的成员内容(如公共属性),但不能更改变量本身。
using System; namespace refDemo { class Program { static void Main(string[] args) { TestChangeStr(new TestClass()); } private static void TestChangeStr(in TestClass test) { test.Str = "Str"; //test = new TestClass();//error System.Console.WriteLine(test.Str); } } class TestClass { public string Str; } }