Kiedy używać klas statycznych w C# [duplikat]

To pytanie ma już odpowiedź tutaj:

Oto co MSDN ma do powiedzenia pod Kiedy używać klas statycznych:

static class CompanyInfo
{
    public static string GetCompanyName() { return "CompanyName"; }
    public static string GetCompanyAddress() { return "CompanyAddress"; }
    //...
}

Użyj klasy statycznej jako jednostki organizacja metod nie związane z poszczególnymi obiektami. Również Klasa statyczna może make your wdrożenie prostsze i szybsze ponieważ nie musisz tworzyć obiekt w celu wywołania jego metod. Przydatne jest porządkowanie metod wewnątrz klasy w sensowny sposób, takie jak metody klasy matematycznej w przestrzeni nazw systemu.

Wydaje mi się, że ten przykład nie obejmuje zbyt wielu możliwych scenariuszy użycia klas statycznych. W przeszłości używałem klas statycznych dla bezpaństwowych pakietów powiązanych funkcji, ale to wszystko. Więc pod jakie okoliczności powinny (a nie powinny) zostać uznane za statyczne?

Author: Ryan, 2008-10-27

11 answers

Swoje przemyślenia o klasach statycznych napisałem we wcześniejszej odpowiedzi Stack Overflow: zajęcia z jedną metodą-najlepsze podejście ?

Kiedyś uwielbiałem klasy użyteczności wypełnione statycznymi metodami. Zrobili wielką konsolidację metod pomocniczych, które w przeciwnym razie leżałyby wokół powodując redundancję i piekło konserwacji. Są bardzo łatwe w użyciu, bez tworzenia instancji, bez usuwania, po prostu fire ' N ' forget. Myślę, że to była moja pierwsza nieświadoma próba stworzenia zorientowanego na usługi Architektura-wiele bezpaństwowych usług, które po prostu wykonywały swoją pracę i nic więcej. Jednak w miarę rozwoju systemu, nadchodzą smoki.

Polimorfizm

Powiedzmy, że mamy metodę UtilityClass.Coś, co radośnie brzęczy. Nagle musimy nieco zmienić funkcjonalność. Większość funkcjonalności jest taka sama, ale musimy zmienić kilka części. Gdyby nie metoda statyczna, moglibyśmy utworzyć klasę derivate I zmienić zawartość metody jako potrzebne. Ponieważ jest to metoda statyczna, nie możemy. oczywiście, jeśli chcemy dodać funkcjonalność przed lub po starej metodzie, możemy utworzyć nową klasę i wywołać starą wewnątrz niej-ale to jest po prostu obrzydliwe.

Interfejs

Statyczne metody nie mogą być definiowane przez interfejsy ze względów logicznych. A ponieważ nie możemy nadpisać metod statycznych, klasy statyczne są bezużyteczne, gdy musimy je przekazywać przez ich interfejs. To sprawia, że nie możemy używać klas statycznych jako element strategii. Możemy naprawić pewne problemy poprzez przekazywanie delegatów zamiast interfejsów .

Testowanie

To w zasadzie idzie w parze z interfejsem, o którym mowa powyżej. Ponieważ nasza zdolność do wymiany implementacji jest bardzo ograniczona, będziemy mieli również problemy z zastąpieniem kodu produkcyjnego kodem testowym. Ponownie, możemy je zawinąć, ale będzie to wymagało od nas zmiany dużej części naszego kodu tylko po to, aby móc zaakceptować wrappery zamiast rzeczywiste obiekty.

Fosters blobs

Ponieważ metody statyczne są zwykle używane jako metody użytkowe, a metody użytkowe Zwykle będą miały różne cele, szybko skończymy z dużą klasą wypełnioną nie spójną funkcjonalnością - najlepiej, aby każda klasa miała jeden cel w systemie. Wolałbym mieć pięć razy więcej zajęć, o ile ich cele są dobrze określone.

Parametr creep

Na początek, że mały słodka i niewinna metoda statyczna może przyjmować jeden parametr. Wraz ze wzrostem funkcjonalności dodawanych jest kilka nowych parametrów. Wkrótce dodawane są kolejne parametry, które są opcjonalne, więc tworzymy przeciążenia metody(lub po prostu dodajemy wartości domyślne, w językach, które je obsługują). Wkrótce mamy metodę, która pobiera 10 parametrów. Tylko pierwsze trzy są naprawdę wymagane, parametry 4-7 są opcjonalne. Ale jeśli parametr 6 jest określony, wymagane jest również wypełnienie 7-9... Gdybyśmy stworzyli klasa z jednym celem robienia tego, co zrobiła ta statyczna metoda, możemy rozwiązać to poprzez wzięcie wymaganych parametrów w konstruktorze i umożliwienie użytkownikowi ustawiania opcjonalnych wartości za pomocą właściwości lub metod ustawiania wielu współzależnych wartości w tym samym czasie. Ponadto, jeśli metoda urosła do tego stopnia złożoności, najprawdopodobniej i tak musi być we własnej klasie.

Wymaganie od konsumentów tworzenia instancji klas bez powodu

Jeden z najczęstsze argumenty to: po co domagać się, aby konsumenci naszej klasy tworzyli instancję dla wywołania tej pojedynczej metody, podczas gdy nie mieli później zastosowania dla tej instancji? Tworzenie instancji klasy jest bardzo tanią operacją w większości języków, więc szybkość nie jest problemem. Dodanie dodatkowej linii kodu do konsumenta to niski koszt stworzenia fundamentu znacznie łatwiejszego do utrzymania rozwiązania w przyszłości. Na koniec, jeśli chcesz uniknąć tworzenia instancji, po prostu utwórz wrapper singleton swojej klasy, która pozwala na łatwe ponowne użycie - chociaż to sprawia, że wymóg, że klasa jest bezpaństwowa. Jeśli nie jest bezpaństwowa, nadal możesz tworzyć statyczne metody owijania, które obsługują wszystko, a jednocześnie zapewniają wszystkie korzyści na dłuższą metę. Na koniec możesz również utworzyć klasę, która ukrywa instancję tak, jakby była singleton: MyWrapper.Instancja jest właściwością, która po prostu zwraca new MyClass();

Tylko Sithowie rozdają absoluty

Oczywiście są wyjątki od mojej niechęci do metod statycznych. Prawdziwe klasy użyteczności, które nie stwarzają żadnego ryzyka wzdęcia są doskonałymi przypadkami dla metod statycznych-System.Konwertuj jako przykład. Jeśli twój projekt jest jednorazowy i nie wymaga przyszłej konserwacji, ogólna Architektura naprawdę nie jest zbyt ważna-statyczna lub niestatyczna, nie ma znaczenia - szybkość rozwoju ma jednak znaczenie.

Standardy, standardy, standardy!

Używanie metod instancji nie powstrzymuje cię od również za pomocą metod statycznych i vice versa. Tak długo, jak istnieje uzasadnienie różnicowania i jest standaryzowane. Nie ma nic gorszego niż przeglądanie warstwy biznesowej z różnymi metodami wdrażania.

 655
Author: Mark S. Rasmussen,
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:33:27

Przy podejmowaniu decyzji, czy utworzyć klasę statyczną czy niestatyczną, musisz przyjrzeć się informacjom, które próbujesz reprezentować. Oznacza to bardziej "oddolny " styl programowania, w którym najpierw skupiasz się na danych, które reprezentujesz. Czy klasa, którą piszesz, jest prawdziwym obiektem, takim jak skała, czy krzesło? Te rzeczy są fizyczne i mają fizyczne atrybuty, takie jak kolor, waga, która mówi, że możesz chcieć utworzyć instancję wielu obiektów o różnych właściwościach. I może chcesz czarne krzesło i czerwone krzesło w tym samym czasie. Jeśli kiedykolwiek potrzebujesz dwóch konfiguracji w tym samym czasie, od razu wiesz, że będziesz chciał utworzyć instancję jako obiekt, aby każdy obiekt mógł być unikalny i istnieć w tym samym czasie.

Z drugiej strony, funkcje statyczne mają tendencję do nadawania większej wartości czynnościom, które nie należą do rzeczywistego obiektu lub obiektu, który można łatwo reprezentować. Pamiętaj, że poprzednikami C # są C++ i C gdzie można po prostu zdefiniować funkcje globalne, które nie egzystować w klasie. To bardziej nadaje się do programowania " top-down". Metody statyczne mogą być używane w tych przypadkach, gdy nie ma sensu, aby "obiekt" wykonywał zadanie. Zmuszając cię do używania klas, ułatwia to grupowanie powiązanych funkcjonalności, co pomaga stworzyć łatwiejszy do utrzymania kod.

Większość klas może być reprezentowana przez statyczne lub niestatyczne, ale kiedy masz wątpliwości, po prostu wróć do swoich korzeni OOP i spróbuj pomyśleć o tym, co reprezentujesz. Na to obiekt, który wykonuje akcję (samochód, który może przyspieszyć, spowolnić, skręcić) lub coś bardziej abstrakcyjnego (jak wyświetlanie danych wyjściowych).

Skontaktuj się ze swoim wewnętrznym OOP i nigdy nie możesz się pomylić!

 131
Author: Despertar,
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-14 14:27:50

W C# 3.0 metody rozszerzeń mogą istnieć tylko w klasach statycznych najwyższego poziomu.

 35
Author: Mark Cidade,
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
2008-10-27 21:04:11

Jeśli używasz narzędzi do analizy kodu (np. FxCop), zaleca się oznaczenie metody static, jeśli ta metoda nie ma dostępu do danych instancji. Uzasadnieniem jest to, że istnieje wzrost wydajności. MSDN: CA1822-Oznacz członków jako statycznych .

To raczej wytyczne niż reguły...
 21
Author: user25306,
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
2018-06-03 08:27:06

Zazwyczaj używam klas statycznych w fabrykach. Na przykład, jest to klasa logowania w jednym z moich projektów:

public static class Log
{
   private static readonly ILoggerFactory _loggerFactory =
      IoC.Resolve<ILoggerFactory>();

   public static ILogger For<T>(T instance)
   {
      return For(typeof(T));
   }

   public static ILogger For(Type type)
   {
      return _loggerFactory.GetLoggerFor(type);
   }
}
Możesz nawet zauważyć, że IoC jest wywoływany za pomocą statycznego accesora. Większość czasu dla mnie, jeśli możesz wywoływać metody statyczne na klasie, to wszystko, co możesz zrobić, więc oznaczam klasę jako statyczną dla dodatkowej jasności.
 12
Author: Rob,
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
2008-10-27 21:11:55

Zacząłem używać klas statycznych, gdy chcę używać funkcji, a nie klas jako jednostki ponownego użycia. Wcześniej chodziło mi o zło klas statycznych. Jednak uczenie się F# sprawiło, że ujrzałem je w nowym świetle.

Co mam na myśli? Powiedzmy, że pracując nad jakimś super suchym kodem, kończę z kilkoma klasami jednej metody. Mogę po prostu wyciągnąć te metody do statycznej klasy, a następnie wstrzyknąć je do Zależności za pomocą delegata. To również gra ładnie z moim dependency injection (DI) kontenerem wyboru Autofac.

Oczywiście przyjmowanie bezpośredniej zależności od statycznej metody jest nadal zazwyczaj złym (istnieją pewne nie-złe zastosowania).

 10
Author: bentayloruk,
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
2016-08-03 16:39:50

Klasy statyczne są bardzo przydatne i mają swoje miejsce, na przykład biblioteki.

Najlepszym przykładem, jaki mogę podać, jest klasa. Net Math, klasy statycznej przestrzeni nazw systemu, która zawiera bibliotekę funkcji matematycznych.

To jest jak Wszystko inne, użyj odpowiedniego narzędzia do pracy, a jeśli nie wszystko może być nadużywane.

Puste odrzucanie klas statycznych jako złych, nie używaj ich, lub mówienie "może być tylko jedna" lub Żadna, jest tak złe,jak używanie ich.

C#.Net zawiera szereg klas statycznych, które są używane tak jak Klasa matematyczna.

Więc biorąc pod uwagę poprawną implementację są one niezwykle przydatne.

Mamy statyczną klasę strefy czasowej, która zawiera wiele funkcji związanych z biznesem, nie ma potrzeby tworzenia wielu instancji klasy, tak jak klasa Math, zawiera ona zestaw globalnie dostępnych funkcji (metod) strefy czasowej w statycznej klasie.

 9
Author: Don,
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-12-15 13:13:30

Używam klas statycznych jako środka do zdefiniowania "dodatkowej funkcjonalności", której obiekt danego typu mógłby użyć w określonym kontekście. Zazwyczaj okazują się klasami użyteczności.

Poza tym myślę, że " używaj klasy statycznej jako jednostki organizacji dla metod nie związanych z konkretnymi obiektami."dość dobrze opisują ich zamierzone użycie.

 8
Author: Trap,
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
2008-10-27 21:05:24

To kolejne stare, ale bardzo gorące pytanie od czasu, gdy OOP zaczął. Istnieje wiele powodów, aby używać(lub nie) klasy statycznej, oczywiście i większość z nich została pokryta mnogością odpowiedzi.

Dodam tylko moje 2 centy do tego, mówiąc, że robię klasę statyczną, gdy ta klasa jest czymś, co byłoby unikalne w systemie i to naprawdę nie miałoby sensu, aby mieć jakiekolwiek jej wystąpienia w programie. Jednak zastrzegam to użycie dla dużych klas. Nigdy nie deklaruję tak małych klasy jak w przykładzie MSDN jako "statyczne", a na pewno nie Klasy, które będą członkami innych klas.

Chciałbym również zauważyć, że metody statyczne i klasy statyczne to dwie różne rzeczy do rozważenia. Główne wady wymienione w zaakceptowanej odpowiedzi są dla metod statycznych . klasy statyczne oferują taką samą elastyczność jak Klasy normalne (gdzie chodzi o właściwości i parametry), a wszystkie stosowane w nich metody powinny być istotne dla celu istnienia klasy.

Moim zdaniem dobrym przykładem kandydata do klasy statycznej jest klasa "FileProcessing", która zawierałaby wszystkie metody i właściwości istotne dla różnych obiektów programu do wykonywania złożonych operacji przetwarzania plików. Prawie nie ma żadnego znaczenia, aby mieć więcej niż jedną instancję tej klasy, a bycie statycznym sprawi, że będzie ona łatwo dostępna dla wszystkiego w twoim programie.

 7
Author: ThunderGr,
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
2014-10-17 07:46:33

Używam tylko klas statycznych dla metod pomocniczych, ale wraz z pojawieniem się C # 3.0, wolałbym używać metod rozszerzeń dla tych metod.

Rzadko używam metod klas statycznych z tych samych powodów, dla których rzadko używam Singletona "wzorca projektowego".

 2
Author: jonnii,
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
2008-10-27 21:00:33

Na podstawie MSDN :

  1. nie można utworzyć instancji dla klas statycznych
  2. jeśli Klasa zadeklarowana jako statyczna, zmienna member powinna być statyczna dla tej klasy
  3. zapieczętowany [nie może być dziedziczony]
  4. nie może zawierać konstruktora instancji
  5. Zarządzanie Pamięcią

Przykład: obliczenia matematyczne (wartości matematyczne) nie zmieniają się [standardowe obliczenia dla zdefiniowanych wartości]

 2
Author: Vicky,
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
2014-12-30 21:19:00