2011-11-28 165 views
0

看看下面的例子:C#指針問題

public void inc(int num) { 
    num++; 
} 

int a = 5; 
inc(a); 

在這種情況下,inc將不會增加a變量本身。它並不指向內存中的相同位置。爲了改變a,我將不得不使用ref

然而,在這個例子中

public static void ExportSelectedRow(GridView gridView, object toObject, int skipCols) 
{ 
    GridViewRow gridViewRow = gridView.SelectedRow; 

    if (toObject is DataTable) 
    { 
     DataTable returnDt = (DataTable)toObject; 
     GridViewColsToDatatable(gridView, returnDt, skipCols); 
     DataRow dr = returnDt.NewRow(); 
     for (int i = skipCols; i < gridViewRow.Cells.Count; i++) 
      dr[i - skipCols] = gridViewRow.Cells[i].Text; 
     returnDt.Rows.Add(dr); 
    } 

} 

protected void GridView1_SelectedIndexChanged(object sender, EventArgs e) { 
    DataTable dt = new DataTable(); 
    GridViewHelper.ExportSelectedRow(GridView1, dt, 1); 
    ... 
} 

選定的行會從GridView1導出到DataTable雖然我沒有,即使在函數中引用它。所以toObject將被更新。看來,

DataTable returnDt = (DataTable)toObject; 

實際上是參考toObject。所以我的問題,爲什麼在這個例子中它是一個參考,但在第一個,它不是?

+0

請注意,'ref'參數值實際上是對字段,局部變量或數組元素的類型化引用 - 它不是指針。可以認爲它是「對被調用代碼中變量的更改應該會導致對調用代碼中的變量進行更改」。它是從引用發生的底層實現中抽象出來的,並且比指針(它可能指向內存中的任何位置,而類型化引用受到高度限制)更加嚴格。 –

回答

12

與其他人會說的相反,在默認情況下一切(是也引用類型)在C#中傳遞的值。與refout他們不是。
但是在參考類型的情況下,通過值傳遞的東西是參考

int當然是一個值類型,DataTable是一個引用類型。

+4

Upvoting你,因爲你是唯一一個絕對正確的人。其他人,請參閱http://www.mbaldinger.com/post/C-reference-types-are-passed-by-value!.aspx – doctorless

+0

只要注意,雖然這**是**正確的,我也認爲它對於初學者程序員來說,將會非常困難。就像古典語言中的指針一樣,這需要時間來「得到它」。因此,我也認爲更詳細的(或更簡單的)解釋也是好的。 –

+0

@Vilx是的,對參考(對一個對象)的引用的概念對於初學者來說確實很困難,儘管很好的例子對此有幫助。儘管如此,我還是遇到了遠遠超出這一點的FAR太多的非BEGINNERS,因此,從一開始就教好它,即使它很難掌握,似乎也會更好。 – phoog

6

C#有參數類型。值類型(結構,枚舉,數字等)和引用類型(對象,字符串等)。

在您的第一個示例中,將值5傳遞給該函數,但在第二個示例中GridView1的引用已通過。

有關定義參數如何傳遞的value-typesreference-types的列表,請參閱MDN。

編輯

爲了更好地definiton請參閱哈羅德的答案。

+0

-1內置或不與內容無關它,並且只有'ref'是嚴格的(和有用的)定義傳遞的。在缺少'ref'的情況下,將複製**值類型**,而對於**引用類型**則只複製參考。編輯:Downvote刪除作爲編輯刪除了明顯的錯誤的東西,並添加更準確的條款,但我仍然認爲它可能措詞*多*更好(什麼是對初學者「簡單類型」)。 – delnan

+0

你忘了'struct's。 –

+0

注意到並更新。 – Chad

1

.NET中有兩種類型的ermm ...類型:值類型和引用類型。不同的是你上面演示的。

基本上每個struct是一個值類型,每個class是一個引用類型。基本類型(如int,decimal,datetime,byte等)也是作爲structs實現的,所以它們是值類型。實際上,它們有點特別,但它們很像結構。

關於此問題,MSDN有一個article,該主題也已在其他地方廣泛報道。只是谷歌「值類型與參考類型」。

3

DataTable是一個參考類型。 int是一個值類型。

C#按值傳遞(除非使用refout)。

  • 當你傳遞一個DataTable一種方法,實際上是傳遞參考的副本。兩個參考文獻均指相同的對象。調用者可以看到對象的修改。
  • 當您通過int時,您傳遞的值爲,其值爲

如果您使用ref關鍵字,它將通過引用傳遞。

0

這裏的區別在於基本類型(如int或double)和對象之間。當你傳遞一個對象時,你傳遞一個對它的引用,而對於內部類型,你正在向該函數傳遞一個值的副本。

結構是有趣的,它們在語法上看起來像類,但通過值(複製)而不是通過引用傳遞。