在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
—— 以下信息均来自网上,后边会稍加自己的总结 —— c#的类型分为两种:值类型和引用类型: 值类型: 简单类型(包括int, long, double等)和结构(structs)都是值类型 引用类型:除了值类型以外的都是引用类型。
ref 关键字使参数按引用传递。其效果是,当控制权传递回调用方法时,在方法中对参数的任何更改都将反映在该变量中。若要使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字。例如:
1 class RefExample 2 { 3 static void Method(ref int i) 4 { 5 i = 44; 6 } 7 static void Main() 8 { 9 int val = 0; 10 Method(ref val); 11 // val is now 44 12 } 13 }
传递到 ref 参数的参数必须最先初始化。这与 out 不同,后者的参数在传递之前不需要显式初始化。有关更多信息,请参见 out。 尽管 ref 和 out 在运行时的处理方式不同,但在编译时的处理方式相同。因此,如果一个方法采用 ref 参数,而另一个方法采用 out 参数,则无法重载这两个方法。例如,从编译的角度来看,以下代码中的两个方法是完全相同的,因此将不会编译以下代码:
1 class CS0663_Example 2 { 3 // Compiler error CS0663: "Cannot define overloaded 4 // methods that differ only on ref and out". 5 public void SampleMethod(out int i) { } 6 public void SampleMethod(ref int i) { } 7 }
但是,如果一个方法采用 ref 或 out 参数,而另一个方法不采用这两个参数,则可以进行重载,如下例所示:
1 class RefOverloadExample 2 { 3 public void SampleMethod(int i) { } 4 public void SampleMethod(ref int i) { } 5 }
属性不是变量,因此不能作为 ref 参数传递。
示例: 按引用传递值类型(如本主题前面所示)是有用的,但是 ref 对于传递引用类型也是很有用的。这允许被调用的方法修改该引用所引用的对象,因为引用本身是按引用来传递的。下面的示例显示出当引用类型作为 ref 参数传递时,可以更改对象本身。
1 class RefExample2 2 { 3 static void Method(ref string s) 4 { 5 s = "changed"; 6 } 7 static void Main() 8 { 9 string str = "original"; 10 Method(ref str); 11 Console.WriteLine(str); 12 } 13 } 14 // Output: changed 15
out 关键字会导致参数通过引用来传递。这与 ref 关键字类似,不同之处在于 ref 要求变量必须在传递之前进行初始化。若要使用 out 参数,方法定义和调用方法都必须显式使用 out 关键字。例如: 1 class OutExample
2 { 3 static void Method(out int i) 4 { 5 i = 44; 6 } 7 static void Main() 8 { 9 int value; 10 Method(out value); 11 // value is now 44 12 } 13 }
尽管作为 out 参数传递的变量不需要在传递之前进行初始化,但需要调用方法以便在方法返回之前赋值。 ref 和 out 关键字在运行时的处理方式不同,但在编译时的处理方式相同。因此,如果一个方法采用 ref 参数,而另一个方法采用 out 参数,则无法重载这两个方法。例如,从编译的角度来看,以下代码中的两个方法是完全相同的,因此将不会编译以下代码:
1 class CS0663_Example 2 { 3 // compiler error CS0663: "cannot define overloaded 4 // methods that differ only on ref and out" 5 public void SampleMethod(out int i) { } 6 public void SampleMethod(ref int i) { } 7 }
示例: 当希望方法返回多个值时,声明 out 方法很有用。使用 out 参数的方法仍然可以将变量用作返回类型,但它还可以将一个或多个对象作为 out 参数返回给调用方法。此示例使用 out 在一个方法调用中返回三个变量。请注意,第三个参数所赋的值为 Null。这样便允许方法有选择地返回值。
1 class OutReturnExample 2 { 3 static void Method(out int i, out string s1, out string s2) 4 { 5 i = 44; 6 s1 = "I've been returned"; 7 s2 = null; 8 } 9 static void Main() 10 { 11 int value; 12 string str1, str2; 13 Method(out value, out str1, out str2); 14 // value is now 44 15 // str1 is now "I've been returned" 16 // str2 is (still) null; 17 } 18 }
使用 ref 和 out 传递数组 与所有的 out 参数一样,在使用数组类型的 out 参数前必须先为其赋值,即必须由被调用方为其赋值。例如:
1 static void TestMethod1(out int[] arr) 2 { 3 arr = new int[10]; // definite assignment of arr 4 }
与所有的 ref 参数一样,数组类型的 ref 参数必须由调用方明确赋值。因此不需要由接受方明确赋值。可以将数组类型的 ref 参数更改为调用的结果。例如,可以为数组赋以 null 值,或将其初始化为另一个数组。例如:
1 static void TestMethod2(ref int[] arr) 2 { 3 arr = new int[10]; // arr initialized to a different array 4 } 5
下面的两个示例说明 out 与 ref 在将数组传递给方法时的用法差异。 示例1 在此例中,在调用方(Main 方法)中声明数组 theArray,并在 FillArray 方法中初始化此数组。然后将数组元素返回调用方并显示。 1 class TestOut
2 { 3 static void FillArray(out int[] arr) 4 { 5 // Initialize the array: 6 arr = new int[5] { 1, 2, 3, 4, 5 }; 7 } 8 9 static void Main() 10 { 11 int[] theArray; // Initialization is not required 12 13 // Pass the array to the callee using out: 14 FillArray(out theArray); 15 16 // Display the array elements: 17 System.Console.WriteLine("Array elements are:"); 18 for (int i = 0; i < theArray.Length; i++) 19 { 20 System.Console.Write(theArray[i] + " "); 21 } 22 } 23 }
结果: Array elements are: 1 2 3 4 5
示例2: 在此例中,在调用方(Main 方法)中初始化数组 theArray,并通过使用 ref 参数将其传递给 FillArray 方法。在 FillArray 方法中更新某些数组元素。然后将数组元素返回调用方并显示。
1 class TestRef 2 { 3 static void FillArray(ref int[] arr) 4 { 5 // Create the array on demand: 6 if (arr == null) 7 { 8 arr = new int[10]; 9 } 10 // Fill the array: 11 arr[0] = 1111; 12 arr[4] = 5555; 13 } 14 15 static void Main() 16 { 17 // Initialize the array: 18 int[] theArray = { 1, 2, 3, 4, 5 }; 19 20 // Pass the array using ref: 21 FillArray(ref theArray); 22 23 // Display the updated array: 24 System.Console.WriteLine("Array elements are:"); 25 for (int i = 0; i < theArray.Length; i++) 26 { 27 System.Console.Write(theArray[i] + " "); 28 } 29 } 30 }
结果: Array elements are: 1111 2 3 4 5555
总结: |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论