Przesyłanie typu referencyjnego przez wartość, przypisane nowej referencji w metodzie

0

W metodzie można zmienić jakieś pole w taki sposób: p.personAge = 99;. Dlaczego w linijce z kodem: p = new Person("Joe", 99); nie tworzy się ten nowy obiekt w tej referencji ? Obiekt przesłaliśmy przez wartość ale jest to obiekt, więc do referencji p powinien zostać wpisany i zapamiętany ten nowy obiekt.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test
{
    class Person
    {
        public string personName;
        public int personAge;

        public Person(string name, int age)
        {
            personName = name;
            personAge = age;
        }
        public Person() { }

        public void Display()
        {
            Console.WriteLine("Name: {0}, Age: {1}", personName, personAge);
        }
    }
    class Program
    {
        static void SendAPersonByValue(Person p)
        {
            p.personAge = 99;

            p = new Person("Joe", 99);
        }
        static void Main(string[] args)
        {
            Person fred = new Person("Fred", 12);
            Console.WriteLine("Before by value call, Person is:");
            fred.Display();

            SendAPersonByValue(fred);
            Console.WriteLine("\nAfter by value call, Person is:");
            fred.Display();
            Console.ReadLine();
        }
    }
}
0
Smutny Mleczarz napisał(a):

Obiekt przesłaliśmy przez wartość ale jest to obiekt, więc do referencji p powinien zostać wpisany i zapamiętany ten nowy obiekt.

Nie powinien.
Przesłałeś referencję przez wartość, czyli w metodzie operujesz na kopii referencji.
Możesz zmieniać zawartość składowych, ponieważ wskazuje ona na ten sam obiekt co oryginalna referencja, ale podczas przypisywania nowego obiektu przypisujesz go tylko do lokalnej kopii.

0

W momencie jak przekazujesz obiekt fred do metody SendAPersonByValue tworzysz nowy obiekt, który wskazuje na freda - możesz wartości freda zmieniać przez obiekt "p" i "fred" - to dwie nazwy dla tego samego obiektu.
Po wykonaniu metody p = new("Joe",99) tak naprawdę sprawiasz, że obiekt "p" wskazuje na nową osobą ( Joe ). Jeśli po przypisaniu nowej osoby wywołasz p.Display() zobaczysz napis (Joe,99).
Dodaj słowo kluczowe ref:


static void SendAPersonByValue(ref Person p)
  

SendAPersonByValue(ref fred);

Dzięki temu nie tworzysz nowego wskazania na ten sam obiekt tylko pracujesz na oryginalnym "fredzie".
Jeśli nie jasno coś wytłumaczyłem to pytaj.
Oczywiście niech ktoś bardziej doświadczony też się wypowie jeśli coś źle opisałem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1