Oskar Dudycz

Pragmatycznie o programowaniu

Ciekawostki - Equals

2011-10-17 oskar dudycz.NET

cover

Dzisiaj b─Öd─Ö si─Ö chwali┼é si─Ö swoj─ů niewiedz─ů. Kilka dni temu kolega zada┼é mi pytanie, kt├│rym skutecznie mnie zagi─ů┼é. Poniewa┼╝ uwa┼╝am, ┼╝e g┼éupot─ů nie jest brak wiedzy co raczej udawanie, ┼╝e si─Ö j─ů posiada, czym pr─Ödzej si─Ö Wam tym pytaniem chwal─Ö.

Co zostanie wy┼Ťwietlone po takim kodzie i dlaczego?

string string1 = "Test";

string string2 = string1;
string string3 = "Test";

Console.WriteLine(Equals(string1, string2)); // 1.
Console.WriteLine(Equals(string1, string3)); // 2.
Console.WriteLine(ReferenceEquals(string1, string2)); //3.
Console.WriteLine(ReferenceEquals(string1, string3)); //4.

Odpowied┼║

Pierwsze i drugie por├│wnanie poka┼╝─ů oczywi┼Ťcie true - Equals por├│wnuj─ůcy stringi o tej samej warto┼Ťci zawsze poka┼╝e true

Drugi i trzeci poka┼╝─ů r├│wnie┼╝ true - tutaj by┼é m├│j b┼é─ůd. Uzna┼éem, ┼╝e skoro string nie jest typem referencyjnym to przy przepisaniu skopiuje on warto┼Ť─ç, a nie przepisze referencj─Ö. W teorii tak powinno by─ç, ale w tym momencie do gry wchodzi Optymalizator Kompilacji. Ten byt czuwa nad tym, aby nasz program dzia┼éa┼é jak najszybciej maskuj─ůc ile si─Ö da nasze b┼é─Ödy. W tym przypadku zauwa┼╝y┼é, ┼╝e nie ma sensu tworzy─ç nie wiadomo ile obiekt├│w, skoro i tak string ma prze┼éadowan─ů metod─Ö Equals i operatoror por├│wnywania. Zamiast generowa─ç kolejne obiekty poprzypina┼é on referencje do jednego obiektu.

Optymalizator jest na tyle sprytny, ┼╝e potrafi si─Ö obroni─ç przed takimi trikami:

string string4 = string1 + String.Empty;

Console.WriteLine(ReferenceEquals(string1, string4));

Dla powy┼╝szego kodu r├│wnie┼╝ wy┼Ťwietli true.

Dopiero co┼Ť takiego potrafi go wprawi─ç w konsternacj─Ö i ka┼╝e mu wy┼Ťwietli─ç upragniony false:

string string5 = (string3 + "a").Replace("a", String.Empty);

Console.WriteLine(ReferenceEquals(string1, string5));
  • ┬ę Oskar Dudycz 2020 - 2021