Dlaczego klasy statyczne są uważane za" klasy " i "typy referencyjne"?

Zastanawiałem się dziś nad systemem Typu C# i CIL i zacząłem się zastanawiać, dlaczego klasy statyczne są uważane za klasy. Jest wiele sposobów, w których nie są one tak naprawdę klasami:

  • Klasa "normalna" może zawierać elementy niestatyczne, Klasa statyczna nie. pod tym względem klasa jest bardziej podobna do struct niż do klasy statycznej, a mimo to struktury mają odrębną nazwę.
  • możesz mieć odniesienie do instancji " normalnej" klasy, ale nie klasy statycznej (mimo że jest ona uważana za "Typ odniesienia"). Pod tym względem klasa jest bardziej podobna do interfejsu niż do klasy statycznej, a mimo to Interfejsy mają odrębną nazwę.
  • Nazwa klasy statycznej nigdy nie może być użyta w miejscu, w którym normalnie pasowałaby nazwa typu: nie możesz zadeklarować zmiennej tego typu, nie możesz jej użyć jako typu podstawowego ani jako parametru typu ogólnego. Pod tym względem klasy statyczne są nieco bardziej jak przestrzenie nazw .
  • "normalna" klasa może zaimplementować interfejsy. Po raz kolejny, to sprawia, że klasy są bardziej podobne do struktur niż do klas statycznych.
  • "normalna" klasa może dziedziczyć z innej klasy.

Dziwne jest również to, że klasy statyczne są uważane za pochodzące z systemu.Obiekt . Chociaż pozwala im to "dziedziczyć" statyczne metody Equals i ReferenceEquals, cel tego dziedziczenia jest wątpliwy tak jak i tak wywołałbyś te metody na obiekcie . C# pozwala nawet na określenie tego bezużytecznego dziedziczenia jawnie na klasach statycznych, ale nie na interfejsach lub strukturach, gdzie implicit derivation from objectand System.ValueType , odpowiednio, rzeczywiście ma cel.

Jeśli chodzi o argument podzbioru cech: klasy statyczne mają podzbiór cech klas, ale mają również podzbiór cech struktur. All of the things które czynią klasę odrębną od innych typów, nie mają zastosowania do klas statycznych.

Jeśli chodzi o argument typeof : przekształcenie klasy statycznej w nowy i inny rodzaj typu nie wyklucza jej użycia w typeof .

Biorąc pod uwagę samą dziwność klas statycznych i brak podobieństw między nimi a" normalnymi " klasami, czy nie powinny one zostać przekształcone w osobny rodzaj typu zamiast specjalnego rodzaju zajęcia?

Author: Timwi, 2010-05-06

10 answers

Tak, są bardzo dziwne. Mają pewne zachowanie podobne do klasy, takie jak możliwość posiadania (statycznych) zmiennych członkowskich i ograniczanie dostępu do członków za pomocą public/private.

Prawie wpisałem tam "public/protected/private" , ale oczywiście protected nie ma sensu, ponieważ nie ma dziedziczenia metod klas statycznych. Myślę, że głównym powodem tego jest to, że ponieważ nie ma przypadków, nie można mieć polimorfizmu, ale to nie jest naprawdę jedyny powód spadek. Polimorfizm jest świetny, ale czasami po prostu chcesz pożyczyć większość funkcjonalności klasy bazowej i dodać kilka własnych rzeczy. Z tego powodu czasami zobaczysz statyczne klasy zamienione na wzorce Singletona, tak aby mogły wykorzystać niektóre funkcje z podstawowego zestawu klas. Moim zdaniem jest to hakerska próba zamknięcia tej luki, która robi się myląca i wprowadza wiele nienaturalnej złożoności. Inną opcją jest agregacja, gdzie Klasa potomna metody po prostu przekazują wywołania do metod klas nadrzędnych, ale wymaga to dużo kodu, aby to wszystko połączyć i nie jest też idealnym rozwiązaniem.

W dzisiejszych czasach klasy statyczne są zwykle używane jako zamiennik metod globalnych, tzn. metod, które po prostu zapewniają funkcjonalność bez powiązania z żadną instancją czegokolwiek. Puryści OO nienawidzą jakiejkolwiek koncepcji wolnego / globalnego czegokolwiek, ale nie chcesz też mieć niepotrzebnej instancji i obiekt unoszący się wokół, jeśli potrzebujesz tylko funkcjonalności, więc statyczna "klasa" zapewnia kompromis pośredni, z którym obie strony mogą się zgodzić.

Więc tak, klasy statyczne są dziwne. Najlepiej byłoby, gdyby można je było podzielić na ich własną koncepcję, która zapewniała elastyczność i lekką łatwość użycia, jaką można uzyskać z metod, które nie muszą być powiązane z instancją( którą mamy teraz z klasami statycznymi), a także grupować te metody w kontenery (które możemy also have now), ale także zapewniają możliwość zdefiniowania Jednostki Bazowej, od której będzie dziedziczyć metody(jest to część, której teraz brakuje). Ponadto byłoby świetnie, że była to oddzielna koncepcja od klas, dokładnie z powodów, które podnosisz, po prostu robi się mylące, ponieważ ludzie naturalnie oczekują, że klasy będą instancjami z właściwościami i metodami, które można tworzyć i niszczyć.

 5
Author: Mike Mooney,
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
2010-05-06 14:00:48

To klasa jeśli chodzi o CLR. To po prostu cukier składniowy w kompilatorze C#.

Nie wydaje mi się, aby było jakieś korzyści z dodania tutaj innej nazwy - zachowują się głównie Jak klasy, które po prostu mają statyczne metody i nie mogą być konstruowane, co jest zwykle rodzajem klasy, która stała się klasą statyczną, kiedy przenieśliśmy się z C# 1 do C# 2.

Pamiętaj, że jeśli chcesz utworzyć dla niego nową nazwę, prawdopodobnie oznacza to nową słowo kluczowe też...

 8
Author: Jon Skeet,
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
2010-05-06 12:46:10

Twoje pytanie brzmi " Dlaczego muszę wpisywać słowa static class X zamiast foobar X". Odpowiedź jest taka, ponieważ programiści już kojarzą słowo "klasa" z "pakietem szczelnie upakowanych funkcjonalności, które ktoś dla mnie napisał". Co, przypadkowo, idealnie pasuje do definicji klas statycznych.

Mogli zamiast tego użyć przestrzeni nazw, tak. Tak się dzieje w C++. Ale termin "Klasa statyczna" ma tutaj zaletę: implikuje mniejszy i wiele więcej ściśle sprzężona grupa funkcjonalności. Na przykład, możesz mieć przestrzeń nazw o nazwie Qt lub boost:: ASIO ale statyczną klasę o nazwie StringUtils lub KWindowSystem (pożyczyć od KDE).

 7
Author: Stefan Monov,
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
2010-05-06 12:52:29

Nie wiem, czy to kwalifikuje się jako odpowiedź, ale chciałbym zwrócić uwagę, że "klasy statyczne" są bardziej pojęciem językowym, a mniej pojęciem CLR. Z punktu widzenia CLR są to tylko klasy, jak każda inna. Do języka należy egzekwowanie wszystkich opisanych zasad.

Jako taka, jedną z zalet obecnej implementacji jest to, że nie dodaje ona większej złożoności do CLR, którą wszystkie języki kierujące CLR musiałyby rozumieć i modelować.

 4
Author: Daniel Pratt,
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
2010-05-06 12:48:03

Jasne, mogły być wykonane w osobny rodzaj rzeczy.

Ale to wymagałoby dodatkowej pracy w CLR, BCL i w zespołach językowych, a ja zostawiłbym inne, ważniejsze rzeczy cofnięte.

Z czysto estetycznego punktu widzenia mogę się z tobą zgodzić.

 3
Author: Eric Gunnerson,
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
2010-05-06 14:43:02

Słuszna uwaga, to pewnie z powodów historycznych, tzn. nie chcieli wymyślać czegoś nowego, ponieważ klasy statyczne już istniały.

C++, Pascal (Delphi) i Java posiadają klasy statyczne, na których opiera się C#.

 0
Author: Guffa,
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
2010-05-06 12:49:36

Klasy statyczne i klasy "normalne" (i struktury) są kontenerami dla kodu wykonywalnego (pola członków, właściwości, metody) i deklarują Type. Gdyby mieli dla tego osobne słowo, zapytalibyśmy odwrotnie ("jeśli są tak podobne, dlaczego nie użyłeś klasy kayword?"). Sugerowałbym "CLR via C#", gdzie jest dobrze wyjaśnione, jak następuje rozwiązywanie typów, wywoływanie metod itp. Działa w ten sam sposób dla" obu " klas, tylko członkowie instancji mają dodatkowy parametr przekazany dla obiekt instancji.

Klasy nie są jak przestrzenie nazw, ponieważ służą tylko do nazywania i odwoływania się. Nie wpływają one na funkcjonalność klasy.

Klasy również różnią się od interfejsów, ponieważ interfejsy są jedynie narzędziami weryfikacji w czasie kompilacji i nie mają własnej funkcjonalności.

 0
Author: Imre Pühvel,
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
2010-05-06 13:24:38

Moim zdaniem klasy statyczne są uważane za takie, ponieważ mogą osadzać prywatne pola, publiczne właściwości i metody, choć są statyczne i mają stałą lokalizację adresu, w której każde wywołanie metody lub właściwości singleton będzie miało swoje odniesienie.

Struktura jest bardziej prawdopodobnym typem wartości, jak wtedy, gdy piszesz:

var struct1 = new Struct1();
var struct2 = struct1;

Każda z właściwości zostanie skopiowana do nowego miejsca pamięci. Ponadto, dzięki strukturze, będziesz mógł zmienić struct2.Property1 wartość bez konieczności jej zmiany w struct1.Property1.

Na opozycję, klasy są w moim rozumieniu typami odniesienia, tak jak piszesz:

var class1 = new Class1();
var class2 = class1;

Tutaj odniesienie jest kopiowane. Oznacza to, że po zmianie class2.Właściwość1, ta sama właściwość również zmieni się w class1.Property1. Dzieje się tak, ponieważ obie klasy wskazują na ten sam adres pamięci.

Jeśli chodzi o klasy statyczne, są one uważane za typy referencyjne, tak jak w przypadku zmiany klasy statycznej.Wartość nieruchomości w metodzie ta zmiana zostanie wypełniona wszędzie tam, gdzie odwołujesz się do tej klasy. Ma tylko jeden adres pamięci i nie może być skopiowany, więc gdy dojdzie do wywołania innej metody lub właściwości, ta nowa wartość będzie przeważać nad Starą. Klasy statyczne mają być udostępniane dla całej aplikacji, więc w aplikacji istnieje tylko jedno odniesienie do niej. Dlatego zmuszanie ich do zachowania się jak Klasa.

Klasa statyczna, mimo że wzór Singletona nie jest, chyba, zachęcony, z wyjątkiem celu absolutnego, może reprezentować rzeczywisty obiekt, podobnie jak klasa lub instancja klasy. Jednakże, ponieważ obiekty unikalne w świecie wydają się być wystarczająco rzadkie, tak naprawdę nie potrzebujemy ich do reprezentowania przedmiotu praktycznego, a jedynie niektórych logicznych, takich jak narzędzia itp., lub innych przedmiotów kosztownych do zaszczepienia.

EDIT W rzeczywistości Klasa statyczna jest tak podobna do klasy, że w Visual Basic nie ma klasy statycznej, a jedynie klasę z elementami statycznymi (współdzielonymi w Visual Basic). Jedynym punktem do rozważenia jest uczynienie tej klasy NotInheritable (zapieczętowaną w C#). Tak więc, C# dostarcza bardziej dorozumianą funkcjonalność, pozwalając zadeklarować klasę statyczną, zamiast ją zapieczętować, z pustym domyślnym konstruktorem, itd. Jest to jakiś skrót, czyli syntaksyczny cukier, jak lubimy to mówić.

Podsumowując, myślę, że nie byłoby żadnych korzyści lub zysków z posiadania nowego słowa kluczowego dla niego.

 0
Author: Will Marcouiller,
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
2010-05-06 16:01:26

Chociaż typy klas, typy wartości i interfejsy zachowują się pod wieloma względami tak, jakby znajdowały się w trzech różnych rodzajach rzeczy, w rzeczywistości wszystkie są opisane za pomocą tego samego rodzaju Type obiektu; pochodzenie typu określa, jaki rodzaj rzeczy to jest. W szczególności, wszystkie typy w. Net są typami klas, z wyjątkiem następujących:

  • Typy inne niż System.Object, które dziedziczą po null; są to Interfejsy.

  • Typy inne niż System.ValueType lub System.Enum, które Dziedzicz z System.ValueType lub System.Enum; są to typy wartości.

  • Kilka typów, takich jak pointers i byrefs, które mogą być identyfikowane przez obiekty Type (niezbędne do takich rzeczy jak typy parametrów), ale nie mają członków tak jak inne typy.

Każdy typ, który ma członków i którego pochodzenie nie spełnia żadnego z powyższych kryteriów, jest uważany za klasę. Klasy statyczne nie są tak naprawdę klasami ze względu na jakąkolwiek szczególną jakość, ale raczej dlatego, że nie mają żadnej jakości, która czyniłaby je czymś innym o nazwie, a nazywanie ich "klasami statycznymi" wydaje się łatwiejsze niż wymyślenie innego terminu, aby je opisać.

 0
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
2013-06-19 21:07:17

A co ze statycznymi konstruktorami? Myślę, że jest to kolejny ważny aspekt, który należy wziąć pod uwagę w swoim porównaniu. Klasy i struktury wspierają je, ale interfejsy i przestrzenie nazw nie.

Budowa implikuje instancję. Podczas gdy implementacja może nie tworzyć "instancji" klasy statycznej, można zobaczyć klasy statyczne jako instancję klasy singleton, do której zawsze może być tylko jedno odniesienie (sama nazwa typowa). Gdybyś mógł dziedziczyć klasy statyczne, przerwij myśl Singletona. Jeśli możesz zadeklarować zmienne tego typu, możesz oczekiwać, że zostaną wyczyszczone przez garbage collector, gdy nie będą już odwoływane.

Dlaczego zamiast struktur są to Klasy? Kiedy myślę o strukturach (typach wartości), myślę o wartościach na stosie. Ich istnienie jest (typowo) bardzo krótkie i są one często kopiowane. To ponownie łamie pojedyncze odniesienie singleton pojęcie powyżej.

 -1
Author: Michael Petito,
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
2010-05-06 14:34:01