Studiuję C # i zastanawiam się, jaki ToString
może być cel i korzyść zastąpienia , jak pokazano w poniższym przykładzie.
Czy można to zrobić w prostszy sposób, używając wspólnej metody bez nadpisywania?
public string GetToStringItemsHeadings
{
get { return string.Format("{0,-20} {1, -20}", "Office Email", "Private Email"); }
}
public override string ToString()
{
string strOut = string.Format("{0,-20} {1, -20}", m_work, m_personal);
return strOut;
}
c#
overriding
3D-kreativ
źródło
źródło
Console.WriteLine(obj.GetToStringItemsHeadings); Console.WriteLine(obj);
lub czegoś podobnego.GetToString
Console.WriteLine(obj.ItemHeadings)
Odpowiedzi:
Czy musisz nadpisać
ToString
? Nie.Czy możesz uzyskać ciąg reprezentujący swój obiekt w inny sposób? Tak.
Ale używając
ToString
, używasz metody, która jest wspólna dla wszystkich obiektów i dlatego inne klasy wiedzą o tej metodzie. Na przykład, ilekroć platforma .NET chce przekonwertować obiekt na reprezentację w postaci ciągu,ToString
jest głównym kandydatem (są inne, jeśli chcesz zapewnić bardziej rozbudowane opcje formatowania).Konkretnie,
wywoływał
yourObject.ToString()
.źródło
@yourObject
i<%=yourObject%>
będzie to „ToString-ed”.ToString
nie powinien w rzeczywistości zmieniać stanu obiektu. Ale to nie jest to, za czym się opowiadałem.ToString
jest przeznaczona do być pominięte. Kropka. Zastrzeżenie tego stwierdzenia nie jest produktywne. Jeśli zrobisz to źle - twoja wina. W rzeczywistości twój uczeń naruszył punkt 4 na oficjalnej liście wytycznych dotyczących unieważniania,ToString
która została zamieszczona w odpowiedzi Davida Andersona.Po prostu dam ci odpowiedź prosto z wytycznych dotyczących projektowania ram z serii .NET Development.
UNIKAJ rzucania wyjątków z
ToString
ROZWAŻ zwracanie unikatowego ciągu powiązanego z instancją.
NALEŻY ROZWAŻYĆ, że dane wyjściowe
ToString
są poprawnymi danymi wejściowymi dla wszystkich metod analizy tego typu.DO upewnić się, że
ToString
nie ma żadnych dostrzegalnych skutków ubocznych.NALEŻY zgłaszać informacje wrażliwe z punktu widzenia bezpieczeństwa poprzez zastąpienie
ToString
tylko po zażądaniu odpowiedniego pozwolenia. Jeśli żądanie uprawnień nie powiedzie się, zwróć ciąg wykluczający informacje wrażliwe na bezpieczeństwo.Object.ToString
Sposób ma być stosowana do celów wyświetlania i diagnostyki. Domyślna implementacja po prostu udostępnia nazwę typu obiektu. Domyślna implementacja nie jest zbyt przydatna i zaleca się przesłonięcie metody.NALEŻY przesłonić,
ToString
gdy można zwrócić interesujący ciąg czytelny dla człowieka. Domyślna implementacja nie jest zbyt przydatna, a implementacja niestandardowa prawie zawsze może zapewnić większą wartość.WOLNO przyjazną nazwę zamiast unikalnego, ale nieczytelnego identyfikatora.
Warto również wspomnieć, ponieważ Chris Sells wyjaśnia również w wytycznych, co
ToString
jest często niebezpieczne dla interfejsów użytkownika. Generalnie moja praktyczna zasada polega na ujawnieniu właściwości, która będzie używana do wiązania informacji z interfejsem użytkownika, i pozostawieniuToString
nadpisania w celu wyświetlania informacji diagnostycznych deweloperowi. Możesz również ozdobić swój typDebuggerDisplayAttribute
.DO starają się zachować ciąg zwrócony z
ToString
krótka. Debugger używaToString
do uzyskania tekstowej reprezentacji obiektu, który ma być pokazany programiście. Jeśli ciąg jest dłuższy niż może wyświetlić debuger, proces debugowania jest utrudniony.Wykonaj formatowanie ciągów na podstawie bieżącej kultury wątku podczas zwracania informacji zależnych od kultury.
Zapewnij przeciążenie
ToString(string format)
lub zaimplementujIFormattable
, jeśli ciąg zwracany zToString
jest wrażliwy na kulturę lub istnieją różne sposoby formatowania ciągu. Na przykładDateTime
zapewnia przeciążenie i implementujeIFormattable
.NIE zwracaj pustego ciągu lub wartości null z
ToString
Przysięgam na te wytyczne i powinieneś to zrobić. Nie mogę powiedzieć, jak poprawił się mój kod tylko dzięki tej jednej wytycznej dotyczącej
ToString
. To samo dotyczy rzeczy takich jakIEquatable(Of T)
iIComparable(Of T)
. Te rzeczy sprawiają, że Twój kod jest bardzo funkcjonalny i nie będziesz żałować poświęcenia dodatkowego czasu na jego implementację.Osobiście nigdy nie używałem
ToString
zbyt wiele w interfejsach użytkownika, zawsze ujawniałem jakąś właściwość lub jakąś metodę. Większość czasu powinieneś używaćToString
do debugowania i celów programistycznych. Służy do wyświetlania ważnych informacji diagnostycznych.źródło
Zastępowanie
ToString()
umożliwia nadanie klasie użytecznej reprezentacji ciągu w postaci czytelnej dla człowieka.Oznacza to, że wynik może ujawnić przydatne informacje o Twojej klasie. Na przykład, jeśli masz klasę Person, możesz wybrać
ToString()
wyświetlanie identyfikatora osoby, jej imienia, nazwiska itp. Jest to niezwykle przydatne podczas debugowania lub logowania.Odnosząc się do twojego przykładu - trudno powiedzieć, czy twoje przesłonięcie jest przydatne, nie wiedząc, czym jest ta klasa - ale sama implementacja jest w porządku.
źródło
Zawsze jest to właściwe, ale dokładnie rozważ intencje stojące za tym, co wyświetlasz
Lepszym pytaniem byłoby zadać:
ToString () jest oknem do stanu obiektu. Nacisk na państwo jako wymóg. Zdecydowanie języki OOP, takie jak Java / C #, nadużywają modelu OOP, hermetyzując wszystko w klasie. Wyobraź sobie, że kodujesz w języku, który nie jest zgodny z silnym modelem OOP; zastanów się, czy użyjesz klasy czy funkcji. Jeśli użyjesz go jako funkcji (tj. Czasownika, akcji), a stan wewnętrzny jest utrzymywany tylko tymczasowo między wejściem / wyjściem, ToString () nie doda wartości.
Jak wspominali inni, ważne jest, aby wziąć pod uwagę to , co wyprowadzasz za pomocą ToString (), ponieważ może być używane przez debuger lub inne systemy.
Lubię wyobrażać sobie metodę ToString jako parametr --help obiektu. Powinien być krótki, czytelny, oczywisty i łatwy do wyświetlenia. Powinien pokazywać to, czym obiekt nie jest tym, co robi . Mając to wszystko na uwadze, rozważmy ...
Przykład zastosowania - analizowanie pakietu TCP:
Nie jest to przechwytywanie sieci tylko na poziomie aplikacji, ale coś bardziej mięsistego, jak przechwytywanie PCAP.
Chcesz przeciążać ToString () tylko dla warstwy TCP, aby móc drukować dane na konsoli. Co by to zawierało? Możesz oszaleć i przeanalizować wszystkie szczegóły TCP (tj. TCP jest złożony) ...
Który obejmuje:
Ale czy chciałbyś otrzymać wszystkie te śmieci, gdybyś wywoływał TCP.ToString () na 100 pakietach? Oczywiście, że nie, byłoby to przeładowanie informacjami. Łatwy i oczywisty wybór jest też najbardziej rozsądny ...
Pokaż, czego ludzie oczekiwaliby zobaczyć:
Wolę rozsądne wyjście, które jest łatwe do przeanalizowania przez ludzi, ale YMMV .
Nic skomplikowanego, dane wyjściowe nie są przeznaczone do analizowania przez maszyny (tj. Chyba, że ludzie nadużywają twojego kodu), zamierzonym celem jest czytelność dla ludzi.
Ale co z resztą tych soczystych informacji, o których mówiłem wcześniej, czy to też nie jest przydatne? Dojdę do tego, ale najpierw ...
ToString () to jedna z najbardziej wartościowych i rzadko wykorzystywanych metod wszechczasów
Z dwóch powodów:
Powód 1 - nie nadużywaj użyteczności ToString ():
Wiele osób używa ToString () do ściągnięcia prostej reprezentacji obiektu w postaci ciągu. Podręcznik języka C # stwierdza nawet:
Wyświetl, a nie dalsze przetwarzanie. To nie znaczy, weź moją ładną reprezentację łańcuchową pakietu TCP powyżej i ściągnij port źródłowy za pomocą regex :: cringe ::.
Prawy sposób robić rzeczy jest ToString call () bezpośrednio na posesji SourcePort (który przy okazji jest ushort tak toString () powinna być już dostępna).
Jeśli potrzebujesz czegoś bardziej niezawodnego do spakowania stanu złożonego obiektu do analizowania maszynowego, lepiej będzie, używając strategii serializacji strukturalnej.
Na szczęście takie strategie są bardzo powszechne:
Uwaga: Chyba że używasz PHP, ponieważ, herp-derp, jest do tego funkcja :: snicker ::
Powód 2 - ToString () nie wystarczy:
Nie widziałem jeszcze języka, który implementowałby to u podstaw, ale widziałem i stosowałem różne odmiany tego podejścia na wolności.
Niektóre z nich obejmują:
Zasadniczo ten włochaty bałagan w stanie pakietu TCP powinien być opisany dla czytelności dla ludzi. Aby uniknąć `` bicia martwego konia '' mówiącego o TCP, `` wskażę palcem '' przypadek nr 1, w którym myślę, że ToString () i ToVerboseString () są niedostatecznie wykorzystywane ...
Przykład zastosowania - tablice:
Jeśli używasz głównie jednego języka, prawdopodobnie czujesz się komfortowo z jego podejściem. Dla ludzi takich jak ja, którzy przeskakują między różnymi językami, liczba różnych podejść może być irytująca.
To znaczy, ile razy mnie to irytowało, przekracza sumę wszystkich palców każdego hinduskiego boga razem wziętych.
Istnieją różne przypadki, w których języki używają wspólnych hacki i mało , że się go w prawo . Niektórzy wymagają ponownego wynalezienia koła, niektórzy robią płytkie wysypisko, inni robią głębokie wysypisko, żaden z nich nie działa tak, jak bym chciał ...
Proszę o bardzo proste podejście:
Gdzie x to liczba elementów w pierwszym wymiarze, a y to liczba elementów w drugim wymiarze lub pewna wartość wskazująca, że drugi wymiar jest postrzępiony (może zakres min / max?).
I:
Miejmy nadzieję, że rzuca to trochę światła na temat, który irytował mnie od dawna. Przynajmniej posypałem małą przynętę na trolle dla PHPersów, aby zignorowali tę odpowiedź.
źródło
ToString()
jest przeznaczony do debugowania, to dlaczego jest to jedyny sposób na wyodrębnienie całego tekstu z StringBuilder - ważna funkcja?Tak naprawdę chodzi przede wszystkim o dobrą praktykę.
ToString()
jest używany w wielu miejscach do zwracania łańcucha reprezentującego obiekt, zazwyczaj do spożycia przez człowieka. Często ten sam ciąg może być użyty do ponownego uwodnienia obiektu (pomyśl o nimint
lubDateTime
na przykład), ale nie zawsze jest to dane (na przykład drzewo może mieć użyteczną reprezentację ciągu, która po prostu wyświetla Licznik, ale wyraźnie nie możesz użyć żeby go odbudować).W szczególności debugger użyje tego do wyświetlenia zmiennej w oknach obserwacyjnych, oknach bezpośrednich itp., Dlatego
ToString
jest nieoceniony przy debugowaniu.Ogólnie rzecz biorąc, taki typ często będzie miał jawnego członka, który również zwraca ciąg. Na przykład para szerokość / długość może mieć, na przykład,
ToDecimalDegrees
zwrot"-10, 50"
, ale może również miećToDegreesMinutesSeconds
, ponieważ jest to inny format dla pary szerokość / długość. Ten sam typ może następnie zastąpićToString
jednym z nich, aby zapewnić `` domyślne '' dla rzeczy takich jak debugowanie, a nawet potencjalnie dla rzeczy takich jak renderowanie stron internetowych (na przykład@
konstrukcja w Razor zapisujeToString()
wynik wyrażenia niebędącego ciągiem do strumień wyjściowy).źródło
object.ToString()
konwertuje obiekt na jego reprezentację w postaci łańcucha. Jeśli chcesz zmienić to, co jest zwracane, gdy użytkownik wywołujeToString()
klasę, którą utworzyłeś, musisz nadpisaćToString()
w tej klasie.źródło
Chociaż myślę, że najbardziej przydatne informacje zostały już podane, dodam moje dwa centy:
ToString()
ma zostać zastąpiony. Jego domyślna implementacja zwraca nazwę typu, która, choć czasami może być przydatna (szczególnie podczas pracy z wieloma obiektami), w większości przypadków nie wystarcza.Pamiętaj, że do celów debugowania możesz polegać
DebuggerDisplayAttribute
. Więcej na ten temat przeczytasz tutaj .Z reguły na POCO zawsze możesz zmienić
ToString()
. POCO to ustrukturyzowana reprezentacja danych, która zwykle może stać się ciągiem.Zaprojektuj ToString tak, aby był tekstową reprezentacją twojego obiektu. Może jego główne pola i dane, może opis, ile elementów jest w kolekcji itp.
Zawsze staraj się dopasować ten ciąg do jednej linii i miej tylko istotne informacje. Jeśli masz
Person
klasę z właściwościami Nazwa, Adres, Numer itp., Zwróć tylko główne dane (Nazwij numer identyfikacyjny).Uważaj, aby nie zastąpić dobrej implementacji
ToString()
. Niektóre klasy frameworków już implementująToString()
. Zastępowanie tej domyślnej implementacji jest złą rzeczą: ludzie będą oczekiwać określonego wynikuToString()
i otrzymają inny.Nie bój się używać
ToString()
. Jedyne, na co bym uważał, to zwracanie poufnych informacji. Poza tym ryzyko jest minimalne. Oczywiście, jak niektórzy zauważyli, inne klasy będą używać Twojego ToString, gdy sięgną po informacje. Ale do diabła, kiedy zwrócenie nazwy typu będzie uważane za lepsze niż uzyskanie niektórych rzeczywistych informacji?źródło
Jeśli tego nie
ToString
zrobisz, otrzymasz implementację klas bazowych, któraObject
jest tylko krótką nazwą typu klasy.Jeśli chcesz jakiejś innej, bardziej znaczącej lub użytecznej implementacji,
ToString
zastąp ją.Może to być przydatne, gdy używasz listy Twojego typu jako źródła danych dla a,
ListBox
ponieważToString
zostanie automatycznie wyświetlony.Inna sytuacja ma miejsce, gdy chcesz przekazać swój typ, do
String.Format
którego wywołuje się wToString
celu uzyskania reprezentacji twojego typu.źródło
Coś, o czym nikt jeszcze nie wspomniał: zastępując
ToString()
, możesz również rozważyć wdrożenie,IFormattable
aby wykonać następujące czynności:Co może być przydatne.
źródło
IFormattible
interfejs.System.Object
będzie miałToString()
metodę możliwą do zastąpienia , ale masz rację, że metoda programu formatującego nieoverride
powinna i powinna odwoływać się doIFormattible
interfejsu w celu zapewnienia pełnej zgodności.IFormattable
przyjmujeIFormatProvider
parametr. Jednak dzięki edycji twojego posta.Jedną z zalet zastąpienia ToString () jest obsługa narzędzi Resharper: Alt + Ins -> "Formatowanie elementów członkowskich" i zapisuje ToString () za Ciebie.
źródło
W niektórych przypadkach ułatwia to odczytywanie wartości klas niestandardowych w oknie nadzoru debugera. Jeśli dokładnie wiem, co chcę zobaczyć w oknie zegarka, kiedy nadpisuję ToString tymi informacjami, to widzę to.
źródło
Podczas definiowania struktur (efektywnie prymitywów użytkownika) uważam, że dobrą praktyką jest dopasowywanie metod
ToString
iParse
iTryParse
, szczególnie w przypadku serializacji XML. W takim przypadku skonwertujesz cały stan na ciąg, aby można go było odczytać później.Klasy są jednak bardziej złożonymi strukturami, które zwykle są zbyt skomplikowane, aby można było używać
ToString
iParse
. IchToString
metody, zamiast zapisywać cały stan, mogą być prostym opisem, który pomaga zidentyfikować ich stan, na przykład unikalnym identyfikatorem, takim jak nazwa lub identyfikator, a może liczbą na liście.Ponadto, jak powiedział Robbie, nadpisywanie
ToString
umożliwia wywołanieToString
odwołania tak podstawowego jak typobject
.źródło
Możesz tego użyć, gdy masz obiekt, który nie ma intuicyjnego znaczenia reprezentacji ciągu, np. Osoba. Więc jeśli chcesz na przykład wydrukować tę osobę, możesz użyć tego zastąpienia do przygotowania jej formatu.
źródło
Object.ToString
Metoda powinna być używana tylko do celów debugowania. Domyślna implementacja pokazuje nazwę typu obiektu, która nie jest zbyt przydatna. Rozważ zastąpienie tej metody, aby zapewnić lepsze informacje do diagnostyki i debugowania. Proszę wziąć pod uwagę, że infrastruktury rejestrowania często używają metody ToString, więc te fragmenty tekstu znajdziesz w swoich plikach dziennika.Nie zwracaj zlokalizowanych zasobów tekstowych w ramach
Object.ToString
metody. Powodem jest to, że metoda ToString powinna zawsze zwracać coś, co deweloper może zrozumieć. Deweloper może nie znać wszystkich języków obsługiwanych przez aplikację.Wdrożyć ten
IFormattable
interfejs, gdy chcesz powrócić zlokalizowaną tekst przyjazne dla użytkownika. Ten interfejs definiuje przeciążenie ToString z parametramiformat
iformatProvider
. FormatProvider ułatwia formatowanie tekstu w sposób uwzględniający kulturę.Zobacz także: Object.ToString i IFormattable
źródło
Prostsze zależy od tego, w jaki sposób Twoja nieruchomość będzie używana. Jeśli potrzebujesz sformatować łańcuch tylko raz, nie ma sensu go zastępować.
Jednak wydaje się, że zastępujesz metodę ToString, aby nie zwracać normalnych danych ciągu dla swojej właściwości, ale aby wykonać standardowy wzorzec formatowania. Ponieważ używasz string.format z dopełnieniem.
Ponieważ powiedziałeś, że się uczysz, ćwiczenie wydaje się również dotyczyć podstawowych zasad programowania obiektowego, związanych z hermetyzacją i ponownym wykorzystaniem kodu.
String.format przyjmujący argumenty, które ustawiłeś dla dopełnienia, zapewnia, że właściwość zostanie sformatowana w ten sam sposób za każdym razem dla każdego kodu, który ją wywołuje. Idąc dalej, wystarczy zmienić to tylko w jednym miejscu zamiast w wielu.
Świetne pytanie, a także świetne odpowiedzi!
źródło
Uważam, że przydatne jest zastąpienie metody ToString w klasach jednostek, ponieważ pomaga to szybko zidentyfikować problemy w testowaniu, zwłaszcza gdy asercja nie powiedzie się, konsola testowa wywoła metodę ToString na obiekcie.
Ale zgodnie z tym, co zostało powiedziane wcześniej, ma dać czytelną dla człowieka reprezentację danego obiektu.
źródło
Jestem zadowolony z Wytycznych Ramowych, o których mowa w innych odpowiedziach. Chciałbym jednak podkreślić cel wyświetlania i debugowania.
Uważaj, jak używasz
ToString
w swoim kodzie. Twój kod nie powinien opierać się na łańcuchowej reprezentacji obiektu. Jeśli tak, należy bezwzględnie zapewnić odpowiednieParse
metody.Ponieważ
ToString
może być używany wszędzie, może być problemem związanym z konserwacją, jeśli chcesz zmienić reprezentację ciągu obiektu w późniejszym czasie. W tym przypadku nie można po prostu zbadać hierarchii wywołań, aby zbadać, czy jakiś kod się nie zepsuje.źródło