Pass by Whatever

Hi!

I am confused by the insistence of both Java and C# that passing a reference type is not pass-by-reference but pass-by-value. I take it that since you get a copy of the reference, they consider it pass-by-value Then, what is passed in pass-by-reference A handle (pointer to a pointer) And, if so, isn't it a copy of the handle that's being passed

As you can see, I am missing something. Please, lay it out simply for me. (Pass-by-value--I get.)

Thx!




Answer this question

Pass by Whatever

  • caroço

    It's not a breaking change at all. All I'm calling for is *compiler* support. out and ref are the same thing in IL, it's the compiler that supports the difference. So to, the compiler could check that variables marked const are not modified within the method call.



  • PradeepTR

    Thanks for asking the question. What I explained to you is how it was explained to me when I asked why C# does not offer const ( or readonly, I guess ) on methods to parameters. I guess where-ever I heard that, it was wrong. I read through my core references last night, which is where I thought I'd seen it also, and found I was wrong. In essence, it would appear that ref is useless on a reference type, it's a reference anyhow. Which once again means that C# is flawed in that there is no way to pass a reference type to a method and mark it as not being modified by the method.



  • s_ursan

    You are correct in the beginning of your question ..

    If we looked at it from a C point of view it is similar to the difference between passing a char * and a char **

    when I am passed a char * I have the address of and can change the data at that location... I cannot however tell the calling function to look at another location.

    C# example ..

    public void Bar(Foo _Foo) {
         _Foo.SomeValue = 4;
    }

    Foo MyFoo = new Foo();
    Bar(myFoo);

    the method Bar has changed MyFoo's SomeValue ...

    when I however change Bar as follows ..

    public void Bar(Foo _Foo) {
         _Foo = new Foo();
         _Foo.SomeValue = 4;
    }

    Foo MyFoo = new Foo();
    Foo tmpFoo = MyFoo;
    Bar(myFoo);
    Assert.AreEqual(tmpFoo, MyFoo); // true when by value, false when by reference.

    When I get out of the function ... MyFoo() will be the same since because it is being passed by value the change of reference is not put back to my original reference. In order for that to work I need to use either the ref or the out keyword.

    Does this make more sense

    Cheers,

    Greg


  • Eusebio Perez

    I am just curious here but how is this a language flaw A recursive deep copy would be required to support this...
  • Mobius17

    in this example, one should probably be using out instead of ref http://msdn.microsoft.com/msdntv/episode.aspx xml=episodes/en/20040624csharpah/manifest.xml

    There is also an "out" keyword, which is a natural complement to the ref parameter modifier. While the ref modifier requires that a value is definitely assigned before passed into a method, the out modifier requires that the method's implementation definitely assigns the parameter a value before returning.


  • Ravs

    I'm not too sure about that the whole "does not persist".

    class Program {
    public static void Main(object[] args) {
    List<String> strings = new List<String>(); // reference object.
    strings.Add("Start");
    AddStuff(strings);
    strings.Add("End");

    for (int i=0;i<strings.Count; i++) {
    Console.WriteLine(stringsIdea);
    }
    }

    public static void AddStuff(List<String> someStrings) {
    for (int i=0; i<10; i++) {
    someStrings.Add(i.ToString());
    }
    }
    }

    this should output..
    Start
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    End


  • gameprix1

    Greg Young wrote:
    I am just curious here but how is this a language flaw A recursive deep copy would be required to support this...


    Not at all. A recursive deep copy is not required to support the notion of "const" reference types in C++!

    "All" that is required (and it's a big "all"!) is that the compiler ensures that you don't modify the data belonging to an object parameter declared as "const". That means introducing all the const-correct forms of all methods and properties, and being const-correct right the way through all the code.

    I think that would be a good thing, but it would be a huge breaking change to the language, and it's very unlikely to ever happen.

  • merk

    AFAIK, a reference type is passed, but if you change the value within the method, then a copy is made. If you use the ref keyword, then the reference continues to refer to the same object. So, it's the same as C++, in that you can specify ref, but it's different in that a deep copy is not made where-ever possible.



  • iPlexor

    http://www.dotnetjunkies.com/WebLog/chris.taylor/archive/2004/06/13/16364.aspx

    http://www.yoda.arachsys.com/csharp/parameters.html

    My explanation is based on my reading of some core Microsoft .NET references, or at least, my recollection of them. From what I read on the links above ( both on the first page of a google search on the subject, BTW ), my understanding may be flawed, I'll need to pull out my books and check again. In the meantime, the above is as deep a discussion of the topic as you could hope to find.



  • Discofunk

    Oddly enough, your second terse response didn't answer all my questions either.

    "a reference type is passed, but if you change the value within the method, then a copy is made" Are you saying that if the reference value is changed, i.e. the reference itself So that, changing the reference variable causes a copy of the reference variable to be made That would mean that it is pass-by-reference unless or until you alter the reference value. No

    No. You are saying that if I use the reference variable to change a value in the referenced object, then the object is copied first and from then on I am using a new reference without realizing it. Yes That still would mean that it is pass-by-reference unless or until you alter the referenced object. (And, sounds like a lot of overhead.)

    "For the reason I stated, the reference does not persist when it is altered in any way". The reference is altered or the object referenced is altered

    Everything I've read and what Java argues is that it is pass-by-value; because, you receive a copy of the reference. What you are saying--and I am not sure what you are saying--is news to me.



  • Mbd

    Thanks for the response, but it doesn't really answer my question, to whit:

    Why is passing a reference not considered pass-by-reference, but using the ref keyword is considered pass-by-reference

    And, what is the actual underlying difference between the two



  • djs1

    Thanks for all the replies!

    I think my cognitive disconnect lay in focusing on the call--whether a copy was passed in--rather than on the result--whether the passed in object--the original--could be modified.



  • dotnetdumps

    I have worked a little initializing an object in a separate method, and if you start with a null object, you do need to pass the reference to change the base object. For example

    static void myMethod (List<object> myList)

    {

    if (myList == null)

    myList=new List<string>();

    if (myList != null)

    list.Add("Test");

    }

    static void myRevisedMethod (ref List<string> myList)

    {

    if (myList == null)

    myList=new List<string>();

    list.Add("Test");

    }

    in the second method, the passed(original list) is modified.


  • bbogdanmircea

    // Why is passing a reference not considered pass-by-reference

    For the reason I stated, the reference does not persist when it is altered in any way

    // but using the ref keyword is considered pass-by-reference

    Because no copy is made when the object is changed, so the original object gets changed.

    // And, what is the actual underlying difference between the two

    Exactly what I said it was :-)



  • Pass by Whatever