正常情況下,乙個整型變數,如(int x=5),在通過方法引數呼叫時,如呼叫方法m(x,x*2),則會產生2個x的副本,如下所示:
而通過帶ref的方法引數呼叫時,不會產生副本。如果在方法中,修改了ref的引數,那麼此改變也會影響到原呼叫的變數。下面是乙個例子:
static
void
main
(string
args)
private
static
void
increanddouble
(ref
int x1,
refint x2)
因為都是ref引數,所以x、x1、x2都是指向同一儲存空間,輸出為 12
在c# 7.0中,ref得到增強,允許定義區域性ref變數,用來共享某個已存在變數的空間,如:
int x=10;
ref int y=ref x;
很多態別都能作為ref區域性變數的初始化,如陣列元素。
乙個使用ref區域性變數修改陣列元素的例子:
var arr =
new(
int x,
int y)[10
];//定義10個元組型別的陣列
for(
int i =
0; i < arr.length; i++
)for
(int i =
0; i < arr.length; i++
)
在沒有ref區域性變數的時候,你可以使用arr[i].x++和arr[i].y*=2來修改,也可以定義中間變數來修改等等。
ref區域性變數也可以應用到字段,如:
class
program
}
輸出為10 10 0
此時tmp變數會阻止gc**第乙個例項物件,直到方法的最後使用tmp之後
ref區域性變數的使用限制:
你必須在返回型別前使用ref關鍵字來接收返回的語句,呼叫的**也宣告乙個用來接收返回的ref區域性變數,如:
int x=10;
refint y=
refrefreturnmethod
(ref x);.
..refint
refreturnmethod
(ref
int p)
ref返回不一定要和ref區域性變數一起使用。如:
int x=10;
refreturnmethod(ref x)++;
輸出和上面一樣都是11.
ref返回對索引器也是有效的,最常用的是返回乙個陣列元素的引用,如:
class
arrayholder
static
void
main
(string
args)
輸出20
從c#7.2開始條件操作符的運算元可以使用ref值,示例如下:
static
(int even,
int odd)
countevenandodd
(ienumerable<
int> values)
return result;
}static
void
main
(string
args)
該**是為統計int型別的list中奇數和偶數的個數,用元組作為方法輸出,最後輸出為:2 ref 關鍵字out關鍵字
using system using system.collections.generic using system.linq using system.text using system.threading.tasks namespace outandref ref修飾方法的引數,在呼叫的時候必須...
ref關鍵字 out關鍵字 區別
ref 和 out 關鍵字比較怪,他們在方法的引數中使用,今天對他們做了認真的研究 msdn上的定義 ref關鍵字使引數按引用傳遞。其效果是,當控制權傳遞 用方法時,在方法中對引數所做的任何更改都將反映在該變數中。若要使用ref引數,則方法定義和呼叫方法都必須顯式使用ref關鍵字。out關鍵字會導致...
ref關鍵字的用法
ref關鍵字通過引用 而非值 傳遞引數。通過引用傳遞的效果是,對所呼叫方法中的引數進行的任何更改都反映在呼叫方法中。例如,如果呼叫方傳遞本地變數表示式或陣列元素訪問表示式,所呼叫方法會將物件替換為 ref 引數引用的物件,然後呼叫方的本地變數或陣列元素將開始引用新物件。若要使用ref引數,方法定義和...