-2

I clearly doesn't understand ref and the scope of a parameter good enough. Can someone tell me why this code works? How can you send dt into a function (I mean it will become a parameter and the scope would be as a local variable right?). So why is dt populated(filled) after fill() has been called?

So my first thought was I'm only sending a reference to dt with fill(), but then I doesn't understand the ref keyword. I thought that's what we had that for.. Do you only have to use ref when the parameter is value by type?

var dt = new DataTable();
using (var cmd = new MySqlCommand(cmdText, connection))
using (var adapter = new MySqlDataAdapter())
{
    adapter.SelectCommand = cmd;
    adapter.Fill(dt); // <---why is ref not needed here?
}
return dt;
radbyx
  • 9,352
  • 21
  • 84
  • 127
  • 2
    `ref` is ment to be used when you change the **reference**, not the **referenced instance**. So you can **modify the referenced instance** without using `ref`, however when you want to **reference another object**, you have to use `ref`. – MakePeaceGreatAgain Mar 25 '19 at 13:40
  • dt is a reference in itself, and you pass the reference. the "ref" keyword is used when passing values. – ThisIsMe Mar 25 '19 at 13:43
  • So the `dt` is a referenced instance? – radbyx Mar 25 '19 at 13:43
  • 2
    `DataTable` is a reference type, and thus it is already passed by reference. If you want to get precise: the reference is passed by value. Adding another `ref` would pass the reference by reference, allowing you to change what `dt` references. Indirection! Fun for the whole family. – Jeroen Mostert Mar 25 '19 at 13:44
  • @JeroenMostert No, it's *not* passed by reference. Saying it's passed by reference is just wrong, misleading, and confusing. – Servy Mar 25 '19 at 13:44
  • @Servy Jeroen already mentioned this saying "If you want to be precise...". – MakePeaceGreatAgain Mar 25 '19 at 13:47
  • 1
    @HimBromBeere Yes, after saying something that's wrong, confusing, and misleading. That's like saying, "An orange is purple, although if you want to be precise it's actually Orange". Going on to correct yourself doesn't make the blatantly incorrect statement any more correct, or any less misleading or confusing. – Servy Mar 25 '19 at 13:51
  • 2
    The correct way to think about this is to not think of `ref` as having anything to do with "references". Imagine that instead of `ref` the keyword is `alias`, and it becomes much more clear. `ref` just means "this variable is another name for the ref'd variable". When you say `int x = 123; M(ref x);` where we have `void M(ref int y)` that just means that `y` is another name for variable `x` - it is an *alias*. – Eric Lippert Mar 25 '19 at 13:56
  • 2
    For more insight on references and values, I recommend Lewis Carroll's *Through the Looking-Glass*, chapter 8. While I see Servy's point, I stand by my comment as written as having some explanatory value without, indeed, being a correct and precise statement on the semantics of C#. Fortunately the question has a duplicate with a complete answer. (Incidentally, "color" is one of those wonderful quasi-physical properties where you can get really deep down the rabbit hole on what it *actually* is relative to our naive understanding, so that's pretty apt.) – Jeroen Mostert Mar 25 '19 at 13:57

1 Answers1

4

ref is ment to be used when you change the reference, not the referenced instance. So you can modify the referenced instance without using ref, however when you want to reference another object, you have to use ref

Having said this Fill will just modify what was passed to it, it won´t create a new DataTable.

On the other hand when you want to return another instance, you have to use ref:

void DoSomething(ref dt)
{
    dt = new DataTable();
    // do something with the new table
}

Now you have two tables, one that was passed to DoSomething and a second one that was created within that method and that doesn´t have anything in common with the former. However the calling code references that new instance now, the original reference is lost.

MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111
  • So when I pass a object of type reference I don't need to use `ref`, except if the reference is new'ed inside the funktion. – radbyx Mar 25 '19 at 13:51
  • You described it better, but I think I got it. I make sense in a way that the object is "new" so I can't know the reference the whole way back. But when or why do you want/need to send in some parameter that will get new'ed up? In cases where it not always will be, or something like that? – radbyx Mar 25 '19 at 13:53
  • 1
    @radbyx `ref`-ing a parameter may be usefull when your method does return multiple things. While this may be also achieved also using `out`-parameter, the `ref` may be used by `DoSomething` before overwriting the reference. So you could call any of its members and **afterwards** reference another instance. – MakePeaceGreatAgain Mar 25 '19 at 14:03