Czy ma sens definiowanie struktury z elementem typu referencyjnego?

Czy jest sens definiowanie struktury za pomocą elementu reference type (a nie definiowanie jej jako klasy)? Na przykład, aby zdefiniować tę strukturę:

public struct SomeStruct
{
    string name;
    Int32  place;
}

Pytam, ponieważ Wiem, że struktura jest typem wartości, a definiowanie w niej jakiegoś typu odniesienia nie ma sensu.

Mam rację? Czy ktoś może to wyjaśnić?
Author: Cody Gray, 2011-04-11

4 answers

Dziewięć razy na dziesięć powinieneś tworzyć klasę, A Nie strukturę. struktury i klasy mają bardzo różną semantykę w C#, w porównaniu do tego, co można znaleźć na przykład w C++. Większość programistów, którzy używają struktury powinna używać klasy, co sprawia, że pytania takie jak ta są zupełnie nieistotne.

Oto kilka szybkich zasad, kiedy powinieneś wybrać strukturę zamiast klasy:

    Nigdy.
    ...Oh, nadal czytasz? Jesteś uparty. W porządku.
  1. gdy istnieje wyraźna potrzeba semantyki typu value, w przeciwieństwie do semantyki typu reference.
  2. Gdy masz bardzo mały typ (zasada kciuka to ślad pamięci mniejszy niż 16 bajtów).
  3. gdy obiekty reprezentowane przez twoją strukturę będą krótkotrwałe i niezmienne (nie ulegną zmianie).
  4. i okazjonalnie, w celach interop z natywnym kodem, który używa struktury.

Ale jeśli podjąłeś świadomą decyzję i jesteś naprawdę przekonany, że NIE , w rzeczywistości potrzebujesz struktury, a nie Klasy, musisz ponownie przejrzeć punkt numer 2 i zrozumieć, czym jest semantyka typu wartości. artykuł Jona Skeeta tutaj powinien przejść długą drogę w kierunku wyjaśnienia rozróżnienia.

Gdy już to zrobisz, powinieneś zrozumieć, dlaczego zdefiniowanie typu odniesienia wewnątrz typu wartości (struct) nie stanowi problemu. Bibliografia typy są jak wskaźniki. Pole wewnątrz struktury nie przechowuje rzeczywistego typu; raczej przechowuje wskaźnik (lub odniesienie)do tego typu. Nie ma nic sprzecznego ani błędnego w deklarowaniu struktury z polem zawierającym Typ odniesienia. Nie "spowolni obiektu" ani nie "wywoła GC", te dwa obawy wyrażasz w komentarzu.

 18
Author: Cody Gray,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:53:56

Deklarowanie pola typu odniesienia oznacza, że musi istnieć spacja do przechowywania wartości odniesienia wskazującego na obiekt docelowy. Tak więc ma sens posiadanie takich pól w strukturach.

 3
Author: Ondrej Tucny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-11 11:57:54

Jestem zainteresowany tym, co bardziej doświadczeni programiści mają do powiedzenia na temat zalet i wad tego, ale rozumiem, że jako typ wartości, zmienna typu SomeStruct byłaby alokowana ze stosu, ale zawierałaby odniesienie do lokalizacji na stercie zawierającej łańcuch znaków.

 2
Author: Andrew Cooper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-11 11:57:04

Ogólnie rzecz biorąc, struktura powinna zawierać publiczne i / lub zmienne pole typu odniesienia tylko wtedy, gdy ma zastosowanie jeden z następujących warunków:

  1. wszystkie instancje tego typu mogą być traktowane jako niezmienne (tak jak w przypadku`string')
  2. semantyka struktury wyraźnie implikuje, że pole identyfikuje obiekt, do którego się odnosi, zamiast ujmować swój stan, i że stan obiektu, do którego odnosi się pole, jest , a nie brany pod uwagę część struktury. Na przykład, w KeyValuePair , można oczekiwać, że 'wartość` zidentyfikuje instancję formularza; przeniesienie formularza wokół ekranu zmieni wartość'.Bounds", ale nie będzie uważane za zmianę "wartości" (która nadal odnosiłaby się do tej samej formy, niezależnie od jej lokalizacji na ekranie)

Jeśli żaden warunek nie ma zastosowania, może być właściwe, aby struktura posiadała pole typu odniesienia, pod warunkiem że spełnione są wszystkie następujące warunki "zastosowanie": {]}

  1. pole Nigdy nie zawiera odniesienia do dowolnego zmiennego obiektu, którego struktura sama nie utworzyła.
  2. odniesienie nie może być nigdy narażone, ani nigdy nie było narażone na jakikolwiek kod, który mógłby w przyszłości zmutować obiekt, do którego się odnosi.
  3. wszystkie mutacje, które kiedykolwiek zostaną wykonane na obiekcie, do którego pole ma się odnosić, muszą zostać wykonane, zanim odniesienie zostanie zapisane w polu.

Innymi słowy, odniesienie do obiektu, które jest używane aby zamknąć stan obiektu (w przeciwieństwie do jego identyfikacji) powinien być przechowywany w polu struct tylko wtedy, gdy nie ma ścieżki wykonania, przez którą obiekt, do którego się odnosi, mógłby zostać zmodyfikowany.

 2
Author: supercat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-19 18:07:14