Obiektowość - wątpliwość związana z referencją

0

Witam,
napisałem sobie klasę do zarządzania tymczasowymi emailami. Wygląda to tak:

class Email {
	public CookieContainer Cookie = new CookieContainer();
	public RestClient Client = new RestClient("https://temp-mail.org");
	public string Address { get; private set; }
	
	public Email() {
		this.Client.CookieContainer = this.Cookie;
	}
	
	public void SetRandomAddress() {
		this.Cookie = new CookieContainer();
		this.Address = this.GetRandomAddress();
	}
	
	public string GetRandomAddress() {
		try {
			//wyślij GET i wydobądz email z źródła strony
		} catch {
			return "";
		}
	}
}

Jest to tylko część kodu, ale mam nadzieję, ze wiecie o co chodzi. Problem w tym, że jak użyję takiego kodu:

Email tempEmail = new Email();
for (int i=0; i<5; i++) {
	tempEmail.SetRandomAddress();
	Console.WriteLine(tempEmail.Address);
}

okazuje się, że w konsoli mam 5x ten sam adres email. Rozwiązanie polega na edycji tego kodu:

public void SetRandomAddress() {
	this.Cookie = new CookieContainer();
	this.Client.CookieContainer = this.Cookie;
	this.Address = this.GetRandomAddress();
}

No i właśnie nie do końca rozumiem dlaczego muszę dodać tą środkową linijkę. Przecież w konstruktorze zdecydowałem, że CookieContainer obiektu Client ma wskazywać na obiekt Cookie mojego emaila. Dlaczego więc muszę robić to jeszcze raz?

0

public Email() {
this.Client.CookieContainer = this.Cookie;
}
Jest tak dlatego, że w tej linijce do this.Client.CookieContainer podajesz referencję do tego co jest w this.Cookie, nie wskazujesz zaś na this.Cookie.

Jeżeli zrobisz this.Cookie = someOtherCookie to w this.Client.CookieContainer będzie stara wartość.

Możesz sobie to wyobrazić, że this.Cookie = value jest szufladą w której jest "etykietka" która nam mówi na co wskazujemy. Jeżeli robisz this.Client.CookieContainer = value to do innej szuflady dajesz tę samą etykietkę, ale jak podmienisz w jednej szufladzie etykietkę to nie znaczy że w magiczny sposób w innych też się zmienią ;)

0

@Pixello: nadal nie rozumiem. Dla przykładu ten program:

    class Program {
        static void Main(string[] args) {
            Person a = new Person();
            a.School.Name = "Szkola osoby a";
            Person b = new Person();
            b.School = a.School;
            Console.WriteLine(b.School.Name);

            Console.ReadLine();
        }
    }

    class Person {
        public string Age { get; set; }
        public School School {get; set;}

        public Person() {
            this.School = new School();
        }
    }

    class School {
        public string Name { get; set; }
    }

działa analogicznie, a wypisuje mi "szkola osoby a".

CookieContainer Cookie = new CookieContainer();
RestClient Client = new RestClient();
Client.CookieContainer = Cookie;

No przecież w tym przypadku Cookie i Client.CookieContainer to jedno i to samo. Po prostu są dwie referencje do tej samej instancji obiektu. Na dobrą sprawę można używać tego naprzemiennie. Źle rozumiem?

0

Jest tak dlatego, że w tej linijce do this.Client.CookieContainer podajesz referencję do tego co jest w this.Cookie, nie wskazujesz zaś na this.Cookie.>

No własnie mi się wydaje, że pisząc:

Person a = new Person();
Person b = new Person();
a = b;

No to do b przypisuję referencję instancji obiektu a tym samym powodując, ze b oraz a wskazują na tą samą instancję obiektu. b wskazuje na to, na co wskazuje a. W takim razie te dwie zmienne referencyjne są sobie równoważne.

0
Pixello napisał(a):

Jeżeli zrobisz this.Cookie = someOtherCookie to w this.Client.CookieContainer będzie stara wartość.

To dlaczego pisząc coś takiego:

Person a = new Person();
a.School.Name = "Szkola osoby a";
Person b = new Person();
b.School = a.School;
Console.WriteLine(b.School.Name);
a.School.Name = "Szkola osoby a po zmianie";
Console.WriteLine(b.School.Name);
Console.ReadLine();

Dostaję dwa wyniki:
Szkola osoby a
Szkola osoby a po zmianie

A zobacz, że przy edycji operowałem na zmiennej referencyjnej a a przy wypisywaniu posługiwałem się zmienną referencyjną b. I zobacz, ze wartość została zaktualizowana, ponieważ a.School jest dokładnie tym samym co b.School ze względu na to, że zmienna referencyjna School zarówno obiektu a i b wskazują na tą samą instancję obiektu.

//Jeśli chodzi o powyższy post, to oczywiście chodziło mi o b = a;

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