Reference type still needs pass by ref?

后端 未结 6 1599
一生所求
一生所求 2020-11-29 04:33

Consider the following code (for simplicity, I did not follow any C# coding rules).

public class Professor
{
    public string _Name;
    
    public Professo         


        
相关标签:
6条回答
  • 2020-11-29 04:44

    You've got pass by reference and reference type mixed up.

    By changing p, you're not changing the thing that p points at, but where p itself is pointing at, so to speak. And because p has not been declared as ref, the reference (to the reference type) is passed by value, and the change to p is not reflected in the code calling ProfessorDetails. Changes to the instance p was pointing at are reflected (as that's a reference type). Would Professor have been a value type, not even those changes would be visible in the calling code.

    0 讨论(0)
  • 2020-11-29 04:49

    Every reference type is pass by value to a method call. So you can modify the data inside your instance because it is pointing to the same place, but if you want to modify the instance you should use ref

    public class Professor
    {
        public string _Name;
    
        public Professor(){}
    
        public Professor(string name)
        {
            _Name=name;
        }
    
        public void Display()
        {
            Console.WriteLine("Name={0}",_Name);
        }
    }
    
    public class Example
    {
        static int Main(string[] args)
        {
            Professor david = new Professor("David");
    
            Console.WriteLine("\nBefore calling the method ProfessorDetails().. ");
            david.Display();
            ProfessorDetails(ref david);
            Console.WriteLine("\nAfter calling the method ProfessorDetails()..");
            david. Display();
        }
    
        static void ProfessorDetails(ref Professor p)
        {
            //change in the name  here is reflected 
            p._Name="Flower";
    
            //Why  Caller unable to see this assignment 
            p=new Professor("Jon");
        }
    }
    
    0 讨论(0)
  • 2020-11-29 04:53

    Regarding on 'passing a reference type' vs 'passing by ref (by using ref key word)', after my research my take away is this:

    If you have a reference type object, and keep this object passing from one method to another, the entire time the objects are pointing to a certain location of the memory. If you work on this object for example by changing the property value, this will cause change to the original object. Think as if, in the different methods you were talking about the same person all the time; and in one method you changed the color of the shirt of that person. So that will cause change in the original person object as well.

    But, on your path of jumping from one method to another, if you create a new reference for the object (as you are doing by writing 'p=new Professor("Jon")'), you are basically breaking the link between the object in a new method and the original object. Your 'p' now references to another location in the memory. So whatever change you make in this new location of the memory, it will have no effect whatsoever to the original object. However if you want to change the original object address and have the link, you need to use ref key word. BECAREFUL TO USE THE REF KEYWORD, because once in any method, you make the original address in the memory change to a new address (by using ref keyword), all the changes to the original object done in other methods are now gone.

    0 讨论(0)
  • 2020-11-29 04:59

    Everything is passed by value in C#. However, when you pass a reference type, the reference itself is being passed by value, i.e., a copy of the original reference is passed. So, you can change the state of object that the reference copy points to, but if you assign a new value to the reference you are only changing what the copy points to, not the original reference.

    When you use the 'ref' keyword it tells the compiler to pass the original reference, not a copy, so you can modify what the reference points to inside of the function. However, the need for this is usually rare and is most often used when you need to return multiple values from a method.

    An example:

    class Foo
    {
        int ID { get; set; }
    
        public Foo( int id )
        {
            ID = id;        
        }
    }
    
    void Main( )
    {
        Foo f = new Foo( 1 );
        Console.WriteLine( f.ID );  // prints "1"
        ChangeId( f );
        Console.WriteLine( f.ID );  // prints "5"
        ChangeRef( f );
        Console.WriteLine( f.ID );  // still prints "5", only changed what the copy was pointing to
    }
    
    static void ChangeId( Foo f )
    {
        f.ID = 5;
    }
    
    static void ChangeRef( Foo f )
    {
        f = new Foo( 10 );
    }
    
    0 讨论(0)
  • 2020-11-29 05:02

    There is a difference between passing a reference and a reference to a reference.

    When you pass an object (of a reference type) the callee can modify the object data through the underlying pointer, but if the callee modifies the reference, when the function returns, the caller does not read the changed reference off the stack. The callee can not change which object is referenced.

    When you pass an object by reference, the callee receives a reference to the reference. The callee has a pointer to the original reference, so can modify the reference (thereby changing what object the reference points to) in addition to modifying the object the reference points to.

    0 讨论(0)
  • 2020-11-29 05:02

    The actual value of p is a reference to the same professor instance as david. Any calls you make on that reference are dereferenced as calls to the same instance as would calls made on david be. However, p is a copy of that reference, it's not the same as david value.

    Thus, when you do p = new Professor(), you are changing the value of the reference variable to point to a new instance. However, that does not modify the david reference, which still points to the old instance.

    If you were to pass p as ref,the value of p would be a reference to the david reference variable. Modifying it would actually modify the david value to point to a new instance.

    0 讨论(0)
提交回复
热议问题