ref out 两种参数传递方式都允许调用者更改传递来的参数的值,两者之间的不同很小,但很重要。两者最重要的不同就是他们所修饰的参数的指定值的方式不同。
带有out参数的方法在被调用之前不需要为out参数指定值,但是,在方法返回之前必须为out参数指定值。很绕口啊,看个例子吧:
class OutExample { // Splits a string containing a first and last name separated // by a space into two distinct strings, one containing the first name and one containing the last name static void SplitName(string fullName, out string firstName, out string lastName) { // NOTE: firstName and lastName have not been assigned to yet. Their values cannot be used. int spaceIndex = fullName.IndexOf(' '); firstName = fullName.Substring(0, spaceIndex).Trim(); lastName = fullName.Substring(spaceIndex).Trim(); } static void Main() { string fullName = "Yuan Sha"; string firstName; string lastName; // NOTE: firstName and lastName have not been assigned yet. Their values may not be used. SplitName(fullName, out firstName, out lastName); // NOTE: firstName and lastName have been assigned, because the out parameter passing mode guarantees it. System.Console.WriteLine("First Name '{0}'. Last Name '{1}'", firstName, lastName); } }
可以把out参数看成是方法的另外的返回值。当一个方法要返回多个函数值时out是非常有用的。
我觉得ref更像引用,使用之前必须初始化。ref修饰的参数在方法内部修改后会反映在方法外部。因为他是引用传递:
class RefExample { static object FindNext(object value, object[] data, ref int index) { // NOTE: index can be used here because it is a ref parameter while (index < data.Length) { if (data[index].Equals(value)) { return data[index]; } index += 1; } return null; } static void Main() { object[] data = new object[] {1,2,3,4,2,3,4,5,3}; int index = 0; // NOTE: must assign to index before passing it as a ref parameter while (FindNext(3, data, ref index) != null) { // NOTE: that FindNext may have modified the value of index System.Console.WriteLine("Found at index {0}", index); index += 1; } System.Console.WriteLine("Done Find"); } }