W .NET, jaka jest różnica między String.Empty
i ""
, i czy są one wymienne, czy też istnieją jakieś podstawowe odniesienia lub problemy związane z lokalizacją wokół równości, String.Empty
które zapewnią, że nie stanowią problemu?
.net
double-quotes
string
johnc
źródło
źródło
string.Empty
i jakie było uzasadnienie zadeklarowania goreadonly
zamiastconst
.Odpowiedzi:
W .NET wcześniejszej do wersji 2.0,
""
tworzy obiekt natomiaststring.Empty
stwarza żadnego obiektu ref , co sprawia, żestring.Empty
bardziej efektywne.W wersji 2.0 i późniejszych .NET wszystkie wystąpienia
""
odnoszą się do tego samego literału łańcuchowego, co oznacza, że""
jest równoważne.Empty
, ale wciąż nie tak szybkie jak.Length == 0
..Length == 0
jest najszybszą opcją, ale.Empty
zapewnia nieco czystszy kod.Aby uzyskać więcej informacji, zobacz specyfikację platformy .NET .
źródło
string.IsNullOrEmpty( stringVar )
.string.Empty
jest polem tylko do odczytu, podczas gdy""
jest stałą czasową kompilacji. Miejsca, w których zachowują się inaczej, to:Domyślna wartość parametru w C # 4.0 lub wyższej
Wyrażenie wielkości liter w instrukcji switch
Podaj argumenty
źródło
String.Empty
w większości przypadków można przekazać argument jako argument Masz rację, że wszystkie przykłady to pokazująyou simply can't put a (run-time) "value" into (compile-time) metadata
i właśnie to pokazują.Poprzednie odpowiedzi były poprawne dla .NET 1.1 (spójrz na datę posta, do którego prowadzą link: 2003). Począwszy od wersji .NET 2.0 i nowszych, nie ma zasadniczo różnicy. W każdym razie JIT będzie odwoływał się do tego samego obiektu na stercie.
Zgodnie ze specyfikacją C #, sekcja 2.4.4.5: http://msdn.microsoft.com/en-us/library/aa691090(VS.71).aspx
Ktoś nawet wspomina o tym w komentarzach do postu Brada Abrama
Podsumowując, praktyczny wynik „” vs. String.Empty wynosi zero. JIT rozwiąże to na końcu.
Przekonałem się osobiście, że JIT jest znacznie mądrzejszy ode mnie, dlatego staram się nie być zbyt sprytny dzięki takim optymalizacjom mikrokompilatora. JIT będzie się rozwijał dla pętli (), usuwał zbędny kod, metody wbudowane itp. Lepiej i w bardziej odpowiednich momentach, niż ja lub kompilator C # mógł kiedykolwiek przewidzieć. Niech JIT wykona swoją pracę :)
źródło
String.Empty
jest polem tylko do odczytu, podczas gdy""
jest stałą . Oznacza to, że nie można użyćString.Empty
instrukcji switch, ponieważ nie jest ona stałą.źródło
default
słowa kluczowego możemy zwiększyć czytelność bez, zapobiegać przypadkowej modyfikacji i mieć stałą czasową kompilacji, choć szczerze mówiąc, nadal uważam, że String.Empty jest bardziej czytelny niż domyślny, ale wolniej pisaćKolejna różnica polega na tym, że String.Empty generuje większy kod CIL. Chociaż kod do odwoływania się do „” i String.Empty ma tę samą długość, kompilator nie optymalizuje konkatenacji ciągów (patrz post na blogu Erica Lipperta ) pod kątem argumentów String.Empty. Następujące równoważne funkcje
wygeneruj tę IL
źródło
"bar " + (ok ? "" : "error")
Powyższe odpowiedzi są technicznie poprawne, ale to, czego możesz naprawdę chcieć użyć, dla najlepszej czytelności kodu i najmniejszej szansy na wyjątek to String.IsNullOrEmpty (s)
źródło
--foo=$BAR
, prawdopodobnie chcesz zauważyć różnicę między nimi, zapominając o ustawieniu zmiennej env a tym, że w ogóle nie przekazują flagi.string.IsNullOrEmpty
to często zapach kodu, który nie sprawdził poprawności danych wejściowych lub robi dziwne rzeczy. Zasadniczo nie powinieneś akceptować pustych ciągów, gdy naprawdę chcesz użyćnull
lub czegoś w rodzaju typu Może / Opcja.Zwykle używam
String.Empty
raczej niż""
z jednego prostego, ale nieoczywistego powodu:""
i""
NIE są takie same, pierwszy ma w rzeczywistości 16 znaków o zerowej szerokości. Oczywiście żaden kompetentny programista nie wstawi do kodu znaków o zerowej szerokości, ale jeśli się tam dostanie, może to być koszmar konserwacji.Uwagi:
W tym przykładzie użyłem U + FEFF .
Nie jestem pewien, czy SO zamierza zjeść te postacie, ale spróbuj sam z jednym z wielu znaków o zerowej szerokości
Natknąłem się na to tylko dzięki https://codegolf.stackexchange.com/
źródło
Użyj
String.Empty
raczej niż""
.Odniesienie:
String.Empty
vs""
źródło
String.Empty nie tworzy obiektu, podczas gdy „” robi. Różnica, jak wskazano tutaj , jest jednak banalna.
źródło
Wszystkie wystąpienia „” są takie same, dosłownie napisany ciąg znaków (lub powinny być). Więc naprawdę nie będziesz rzucał nowego obiektu na stos za każdym razem, gdy użyjesz „”, ale po prostu utworzysz odniesienie do tego samego, internowanego obiektu. Powiedziawszy to, wolę ciąg. Pusty. Myślę, że dzięki temu kod jest bardziej czytelny.
źródło
To po prostu nie ma znaczenia!
Niektóre wcześniejsze dyskusje na ten temat:
http://www.codinghorror.com/blog/archives/000185.html
http://blogs.msdn.com/brada/archive/2003/04/22/49997.aspx
http://blogs.msdn.com/brada/archive/2003/04/27/50014.aspx
źródło
ldstr
wypycha odwołanie do nowego obiektu do literału ciągu zapisanego w metadanych.ldsfld
wypycha wartość pola statycznego na stos ocenyZwykle używam
String.Empty
zamiast tego,""
ponieważ IMHO jest jaśniejsze i mniej VB.źródło
Oto niektóre wyniki Roslyn x64 ze stycznia 2019 r. Pomimo konsensusowych uwag innych odpowiedzi na tej stronie, nie wydaje mi się, aby obecny JIT x64 traktował wszystkie te przypadki identycznie, kiedy wszystko zostało powiedziane i zrobione.
Zauważ jednak w szczególności, że tylko jeden z tych przykładów w rzeczywistości kończy się wywołaniem
String.Concat
i domyślam się, że dzieje się tak z niejasnych powodów poprawności (w przeciwieństwie do nadzoru nad optymalizacją). Inne różnice wydają się trudniejsze do wyjaśnienia.default (String) + {default (String), "", String.Empty}
„” + {default (String), ””, String.Empty}
String.Empty + {default (String), "", String.Empty}
Szczegóły testu
źródło
Mówiąc o tym z punktu widzenia Entity Framework: wydaje się, że wersje EF 6.1.3 traktują String.Empty i "" inaczej podczas walidacji.
string.Empty jest traktowany jako wartość zerowa do celów sprawdzania poprawności i zgłosi błąd sprawdzania poprawności, jeśli zostanie użyty w polu Required (przypisanym); gdzie jako „” przejdzie sprawdzanie poprawności i nie zgłosi błędu.
Ten problem można rozwiązać w EF 7+. Odniesienie: - https://github.com/aspnet/EntityFramework/issues/2610 ).
Edycja: [Wymagane (AllowEmptyStrings = true)] rozwiąże ten problem, umożliwiając sprawdzenie poprawności ciągu.Empty.
źródło
Ponieważ String.Empty nie jest stałą czasową kompilacji, nie można jej użyć jako wartości domyślnej w definicji funkcji.
źródło
public void test(int i=0, string s=string.Empty) {}
nie będzie się kompilować i powie „Domyślna wartość parametru dla 's' musi być stałą czasu kompilacji. Odpowiedź OP działa.Gdy wizualnie skanujesz kod, „” jest pokolorowane w sposób pokolorowany. string.Empty wygląda jak zwykły dostęp do klasy. Podczas szybkiego spojrzenia łatwiej jest dostrzec „” lub zinterpretować znaczenie.
Znajdź łańcuchy (kolorystyka przepełnienia stosu nie pomaga, ale w VS jest to bardziej oczywiste):
źródło
\u00ad
.Wszyscy tutaj udzielili dobrych teoretycznych wyjaśnień. Miałem podobne wątpliwości. Więc wypróbowałem na nim podstawowe kodowanie. I znalazłem różnicę. Oto różnica.
Wydaje się więc, że „Null” oznacza absolutnie nieważne, a „String.Empty” oznacza Zawiera pewną wartość, ale jest pusta.
źródło
""
kontrastring.Empty
.null
Wspomniano tylko o próbie stwierdzenia, czy ciąg znaków jest pusty .