0

Take a look at the following example:

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

int a = 5;
inc(a);

In this case, inc won't increment the a variable itself. It is not pointing to the same location in the memory. In order to change a, I'll have to use ref.

However, in this example

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);
    ...
}

the selected row will be exported from the GridView1 into DataTable although I didn't even referenced it in the function. So the toObject will be updated. It seems that

DataTable returnDt = (DataTable)toObject;

is actually referencing to the toObject. So my question, why in this example it is a reference, but in the first one, it is not?

1
  • Note that a 'ref' parameter value is really a typed reference to a field, local variable or array element--it is not a pointer. Think of it as saying "changes to the variable in the called code should cause a change to the variable in the calling code." It's abstracted from the underlying implementation of how the referencing occurs and it is more tightly constrained than a pointer (which could potentially refer to anywhere in memory, whereas a typed reference is highly restricted.) Commented Nov 28, 2011 at 21:43

5 Answers 5

12

Contrary to what other people are going to say, by default everything (yes also reference types) in C# is passed by value. With ref or out they aren't.
But in the case of reference types, the thing that is passed by value is a reference.

int is of course a value type, DataTable is a reference type.

Sign up to request clarification or add additional context in comments.

3 Comments

Upvoting you because you're the only one that is absolutely correct. Others, see mbaldinger.com/post/C-reference-types-are-passed-by-value!.aspx
Just to note, while this is correct, I also think that it would be very difficult for a beginner programmer to wrap his head around. Like pointers in classical languages this will take time to "get it". Hence I also think that a more elaborate (or simpler) explanation would also be good.
@Vilx yes, the concept of a reference to a reference (to an object) is definitely difficult for beginners to wrap their heads around, though good examples help with that. I have run into FAR TOO MANY NON-BEGINNERS who are STILL confused by this, however, so it seems better to teach it properly from the start, even if it is difficult to grasp.
6

C# has parameter types. Value Types (structs, enums, numbers, etc) and Reference Types (objects, strings, etc).

In your first example the value 5 is passed to the function, but in the second example GridView1's reference is passed.

See MDN for a list of value-types and reference-types which define how parameters are passed.

EDIT

For a better definiton please see harold's answer.

2 Comments

-1 Builtin or not has nothing to do with it, and only ref is pass-by-reference by the strict (and useful) definition. In the absence of ref, value types are copied, while for reference types only the reference is copied. Edit: Downvote removed as the edits removed the blatantly wrong stuff and added more accurate terms, although I still think it could be phrased much better (what's a "simple type" for starters?).
@Chad: value type and reference type are two different types of data types (see msdn.microsoft.com/en-us/library/t63sy5hs(v=vs.80).aspx for details). There are also different types of parameters: ref and out are two examples. Note that ref can be applied to value-type parameters or to reference-type parameters. The two concepts are independent. See @harold's answer which seems to be the only one to make this distinction correctly.
3

DataTable is a reference type. int is a value type.

C# passes by value (unless ref or out is used).

  • When you pass a DataTable to a method, you are actually passing a copy of the reference. Both references refer to the same object. Modifications to the object will be visible to the caller.
  • When you pass an int you're passing a copy of the value.

If you use the ref keyword, it will pass by reference instead.

Comments

1

There are two types of ermm... types in .NET: Value types and reference types. The difference is exactly what you've demonstrated above.

Basically every struct is a value type and every class is a reference type. Basic types (like int, decimal, datetime, byte, etc.) are also implemented as structs, so they are value types. Well, actually, they're a bit special, but they are quite like structs.

MSDN has an article about this, and the topic has been extensively covered in other places too. Just google for "value types vs reference types".

Comments

0

The difference here is between a base type such as an int or double and an object. When you pass an object you are passing a reference to it, while with intrinsic types yo are passing a copy of the value to the function.

structs are interesting in that they syntactically look like classes but are passed by value (copied) instead of by reference.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.