2011-11-28 168 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)和对象之间。当你传递一个对象时,你传递一个对它的引用,而对于内部类型,你正在向该函数传递一个值的副本。

结构是有趣的,它们在语法上看起来像类,但通过值(复制)而不是通过引用传递。