Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#指针问题_C#_Pointers_Reference - Fatal编程技术网

C#指针问题

C#指针问题,c#,pointers,reference,C#,Pointers,Reference,请看以下示例: 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 = grid

请看以下示例:

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);
    ...
}
实际上引用的是
对象
。所以我的问题是,为什么在这个例子中它是一个引用,而在第一个例子中它不是?

C#有参数类型。值类型(结构、枚举、数字等)和引用类型(对象、字符串等)

在第一个示例中,值
5
被传递给函数,但在第二个示例中
GridView1
的引用被传递

有关定义参数传递方式的和的列表,请参见MDN

编辑


有关更好的定义,请参见harold的答案。ermm有两种类型。。。NET中的类型:值类型和引用类型。区别正是您在上面演示的

基本上,每个
struct
都是一个值类型,每个
class
都是一个引用类型。基本类型(如int、decimal、datetime、byte等)也实现为结构,因此它们是值类型。实际上,它们有点特别,但它们很像结构


MSDN对此有自己的看法,其他地方也广泛讨论了这个话题。只需谷歌搜索“值类型vs引用类型”。

DataTable
是一种引用类型
int
是一种值类型

C#按值传递(除非使用
ref
out

  • 当您将
    DataTable
    传递给方法时,实际上是在传递引用的副本。两个引用引用同一个对象。调用者可以看到对对象的修改
  • 当您传递一个
    int
    时,您传递的是该值的一个副本

如果您使用
ref
关键字,它将通过引用传递。

与其他人将要说的相反,默认情况下,C#中的所有内容(也是引用类型)都是通过值传递的。使用
ref
out
时,它们不是。
但是在引用类型的情况下,通过值传递的是引用


int
当然是一种值类型,
DataTable
是一种引用类型。

这里的区别是int或double等基本类型与对象之间的区别。当您传递一个对象时,您传递的是对它的引用,而对于内在类型,您传递的是值的副本到函数


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

-1内置或不内置与此无关,只有
ref
通过严格(且有用)的定义通过引用传递。如果没有
ref
,则复制值类型,而对于引用类型,仅复制引用。Edit:Downvote被删除,因为编辑删除了明显错误的内容并添加了更准确的术语,尽管我仍然认为它的措辞可以更好(对于初学者来说,“简单类型”是什么?。@Chad:value类型和reference类型是两种不同的数据类型(有关详细信息,请参阅)。还有不同类型的参数:
ref
out
是两个示例。请注意,
ref
可应用于值类型参数或引用类型参数。这两个概念是独立的。请看@harold的答案,这似乎是唯一一个正确区分这一点的答案。投票给你,因为你是唯一一个绝对正确的人。其他人,请注意,虽然这是正确的,但我也认为对于初学者来说,绞尽脑汁是非常困难的。就像经典语言中的指针一样,这需要时间来“理解”。因此,我也认为更详细(或更简单)的解释也很好。@Vilx是的,引用(对象)的概念对于初学者来说肯定很难理解,尽管好的例子有助于理解。然而,我遇到了太多的非初学者,他们仍然对此感到困惑,因此从一开始就正确地教授它似乎更好,即使它很难掌握。请注意,“ref”参数值实际上是对字段、局部变量或数组元素的类型化引用,而不是指针。可以将其视为“对被调用代码中的变量的更改应该导致对调用代码中的变量的更改”。它是从引用如何发生的底层实现中抽象出来的,并且比指针受到更严格的约束(它可能引用内存中的任何位置,而类型化引用受到高度限制。)
DataTable returnDt = (DataTable)toObject;