Czy podczas tworzenia klasy z wewnętrznymi metodami prywatnymi, zwykle w celu ograniczenia duplikacji kodu, które nie wymagają użycia pól instancji, istnieją zalety związane z wydajnością lub pamięcią w przypadku deklarowania metody jako statycznej?
Przykład:
foreach (XmlElement element in xmlDoc.DocumentElement.SelectNodes("sample"))
{
string first = GetInnerXml(element, ".//first");
string second = GetInnerXml(element, ".//second");
string third = GetInnerXml(element, ".//third");
}
...
private static string GetInnerXml(XmlElement element, string nodeName)
{
return GetInnerXml(element, nodeName, null);
}
private static string GetInnerXml(XmlElement element, string nodeName, string defaultValue)
{
XmlNode node = element.SelectSingleNode(nodeName);
return node == null ? defaultValue : node.InnerXml;
}
Czy istnieje korzyść z deklarowania metod GetInnerXml () jako statycznych? Proszę o brak opinii, mam opinię.
c#
performance
NerdFury
źródło
źródło
Odpowiedzi:
Ze strony reguły FxCop na ten temat:
źródło
Kiedy piszę zajęcia, większość metod dzieli się na dwie kategorie:
Metody statyczne są przydatne, ponieważ po prostu patrząc na jego podpis, wiesz, że wywołanie nie używa ani nie modyfikuje stanu bieżącej instancji.
Weź ten przykład:
Jeśli instancja stanu biblioteki kiedykolwiek się popsuła, a ja próbuję dowiedzieć się, dlaczego, mogę wykluczyć winowajcę ze względu na jego podpis.
Staram się komunikować jak najwięcej z podpisem metody lub funkcji i jest to doskonały sposób na zrobienie tego.
źródło
Library
ma pole instancjiList<Book> _books
przechowywać go Książki (nie jak chcesz zaprojektowaćLibrary
klasę prawdopodobnie ale w / e), i przekazuje tę listęfindBook
, i który wywołuje metody statycznebooks.Clear()
albobooks.Reverse()
i tak dalej. Jeśli dasz statycznej metodzie dostęp do odwołania do jakiegoś stanu zmiennego, wtedy ta statyczna metoda może bardzo zepsuć twój stan.Wywołanie metody statycznej generuje instrukcję wywołania w języku pośrednim Microsoft (MSIL), podczas gdy wywołanie metody instancji generuje instrukcję callvirt, która sprawdza również odwołania do obiektów zerowych. Jednak przez większość czasu różnica między nimi nie jest znacząca.
src: MSDN - http://msdn.microsoft.com/en-us/library/79b3xss3(v=vs.110).aspx
źródło
Tak, kompilator nie musi przekazywać niejawnego
this
wskaźnika dostatic
metod. Nawet jeśli nie użyjesz go w metodzie instancji, nadal jest przekazywany.źródło
Będzie to nieco szybsze, ponieważ nie przekazano tego parametru (chociaż koszt wydajności wywołania metody jest prawdopodobnie znacznie większy niż oszczędność).
Powiedziałbym, że najlepszym powodem, dla którego mogę wymyślić prywatne metody statyczne, jest to, że nie możesz przypadkowo zmienić obiektu (ponieważ nie ma tego wskaźnika).
źródło
To zmusza cię do zapamiętania, aby zadeklarować również elementy o zasięgu klasy, których funkcja używa również jako statyczne, co powinno oszczędzić pamięć tworzenia tych elementów dla każdej instancji.
źródło
Bardzo wolę, aby wszystkie prywatne metody były statyczne, chyba że tak naprawdę nie mogą być. Wolałbym następujące:
nad każdą metodą uzyskującą dostęp do pola instancji. Dlaczego to? Ponieważ ponieważ ten proces obliczania staje się bardziej złożony, a klasa kończy się na 15 metodach prywatnego pomocnika, NAPRAWDĘ chcę móc wyciągnąć je do nowej klasy, która zawiera semantycznie znaczący podzbiór kroków.
Kiedy
MyClass
pojawia się więcej zależności, ponieważ potrzebujemy logowania, a także musimy powiadomić serwis internetowy (proszę wybaczyć przykładowe przykłady), wtedy naprawdę pomocne jest łatwe sprawdzenie, jakie metody mają zależności.Narzędzia takie jak R # pozwalają wyodrębnić klasę z zestawu prywatnych metod statycznych za pomocą kilku naciśnięć klawiszy. Spróbuj to zrobić, gdy wszystkie prywatne metody pomocnicze są ściśle powiązane z polem instancji, a zobaczysz, że może to być ból głowy.
źródło
Jak już wspomniano, metody statyczne mają wiele zalet. Jednak; pamiętaj, że będą żyć na stosie przez cały okres użytkowania aplikacji. Niedawno spędziłem dzień na śledzeniu wycieku pamięci w usłudze Windows ... przeciek został spowodowany przez prywatne metody statyczne w klasie, która zaimplementowała IDisposable i była konsekwentnie wywoływana z instrukcji using. Za każdym razem, gdy ta klasa została utworzona, pamięć była rezerwowana na stercie dla metod statycznych w klasie, niestety, gdy klasa została zutylizowana, pamięć dla metod statycznych nie była zwalniana. Spowodowało to, że ślad tej usługi zużył dostępną pamięć serwera w ciągu kilku dni z przewidywalnymi rezultatami.
źródło