W języku C # chcę zainicjować wartość ciągu pustym ciągiem.
Jak mam to zrobić? Jaka jest właściwa droga i dlaczego?
string willi = string.Empty;
lub
string willi = String.Empty;
lub
string willi = "";
albo co?
c#
.net
string
initialization
Daniel Kreiseder
źródło
źródło
Odpowiedzi:
Używaj tego, co Ty i Twój zespół uznacie za najbardziej czytelne.
Inne odpowiedzi sugerują, że za każdym razem tworzony jest nowy ciąg
""
. Nie jest to prawdą - ze względu na internowanie ciągów zostanie on utworzony albo raz na zespół, albo raz na AppDomain (lub ewentualnie raz dla całego procesu - nie jestem pewien z tej strony). Różnica ta jest znikoma - masowo, masowo nieistotna.Jednak to, co uważasz za bardziej czytelne, to inna sprawa. Jest to subiektywne i będzie się różnić w zależności od osoby - dlatego sugeruję, abyś przekonał się, jak lubi większość ludzi w zespole i wszyscy zachowują spójność. Osobiście uważam, że
""
łatwiej jest czytać.Argument, że
""
i" "
są łatwo pomylić z siebie naprawdę nie myć się ze mną. O ile nie używasz czcionki proporcjonalnej (a ja nie współpracowałem z żadnymi programistami, którzy to robią), dość łatwo jest odróżnić.źródło
string.Empty
nie jest stała . Oznacza to, że w wielu przypadkach, w których wymagana jest stała czasowa kompilacji,string.Empty
nie jest nawet legalna. Obejmuje tocase ""
bloki wswitch
instrukcjach, wartości domyślne parametrów opcjonalnych , parametry i właściwości w stosowaniu atrybutów oraz wiele innych sytuacji (pozostawionych czytelnikowi). Biorąc pod uwagę, żestring.Empty
jest to niedozwolone w niektórych typowych sytuacjach, lepiej zastosować""
konwencję -w każdym innym miejscu.Naprawdę nie ma różnicy z punktu widzenia wydajności i generowanego kodu. W testach wydajności poruszali się tam iz powrotem, między którymi jedno było szybsze w porównaniu do drugiego i tylko o milisekundy.
Patrząc na kod za kulisami, naprawdę nie widzisz żadnej różnicy. Jedyną różnicą jest IL, która
string.Empty
korzysta z opcoduldsfld
i""
używa opcoduldstr
, alestring.Empty
dzieje się tak tylko dlatego, że jest statyczna i obie instrukcje robią to samo. Jeśli spojrzysz na zespół, który jest produkowany, jest dokładnie taki sam.Kod C #
Kod IL
Kod zestawu
źródło
Najlepszy kod w ogóle nie ma kodu :
W rezultacie, mniej kod jest lepszy kod: Wolę
""
sięstring.Empty
lubString.Empty
. Te dwa są sześć razy dłuższe bez dodatkowej korzyści - z pewnością bez dodatkowej przejrzystości, ponieważ wyrażają dokładnie te same informacje.źródło
i
jest lepsza niż długa nazwa zmiennej. Zawsze bardziej preferowane są nawet bardziej ogólne, krótsze nazwy zmiennych, które przekazują te same informacje , w tej samej przejrzystości. Po prostu, aby wyrazić niezbędne informacje, potrzebujesz pewnej długości postaci i nie zaprzeczam temu (nikt nie jest).Jedną różnicą jest to, że jeśli używasz
switch-case
składni, nie możesz pisać,case string.Empty:
ponieważ nie jest to stała. DostajeszCompilation error : A constant value is expected
Spójrz na ten link, aby uzyskać więcej informacji: string-empty-versus-empty-quotes
źródło
switch
stwierdzenie jest bardzo dobrym przykładem. Ponadto, jeśli podasz parametr opcjonalny, npvoid MyMethod(string optional = "") { ... }
. Nie będzie można go użyćstring.Empty
. A potem oczywiście, jeśli chcesz zdefiniowaćconst
pole lub zmienną lokalną,const string myString = "";
znowu""
jest jedyną opcją. Gdyby tylkostring.Empty
było stałym polem, nie byłoby różnicy. Ale tak nie jest, więc w niektórych przypadkach musisz użyć""
. Dlaczego więc nie korzystać""
cały czas?string.Empty
uniemożliwia osiągnięcie spójności w bazie kodu: musisz użyć dwóch różnych bytów, aby wyrazić to samo. I dodać do listy rzeczy, których nie możesz zrobić: nie możesz używaćstring.Empty
z atrybutami .Wolałbym
string
sięString
. Wybierając sięstring.Empty
na""
to kwestia wyboru jednego i wystaje z niego. Zaletą używaniastring.Empty
jest to, że masz na myśli to, co masz na myśli, i nie kopiujesz przypadkowo znaków niedrukowalnych, jak"\x003"
w twoim""
.źródło
""
jest niebezpieczny, gdy kopiowanie / wklejanie jest nieważny, twierdzę, ponieważ nigdy nie kopiujesz / wklejasz pustego łańcucha. Oczywiście w przypadku innych łańcuchów zawsze należy pamiętać.Nie zamierzałem się wtrącać, ale widzę, że wyrzucano tutaj złe informacje.
Ja osobiście wolę
string.Empty
. To jest osobista preferencja i przychylam się do woli każdego zespołu, z którym pracuję na zasadzie indywidualnej.Jak wspomnieli inni, nie ma żadnej różnicy między
string.Empty
iString.Empty
.Ponadto jest to mało znany fakt, że użycie „” jest całkowicie dopuszczalne. Każde wystąpienie „” w innych środowiskach utworzy obiekt. Jednak .NET internalizuje swoje łańcuchy, więc przyszłe instancje wyciągną ten sam niezmienny ciąg z puli wewnętrznej, a każde uderzenie wydajności będzie znikome. Źródło: Brad Abrams .
źródło
Osobiście wolę „”, chyba że istnieje uzasadniony powód do czegoś bardziej złożonego.
źródło
String.Empty
istring.Empty
są równoważne.String
to nazwa klasy BCL;string
to jego alias C # (lub skrót, jeśli chcesz). To samo co zInt32
iint
. Zobacz dokumenty, aby uzyskać więcej przykładów.Jeśli chodzi
""
o mnie, nie jestem do końca pewien.Osobiście zawsze używam
string.Empty
.źródło
Prawie każdy programista będzie wiedział, co znaczy „”. Osobiście zetknąłem się z String.Empty po raz pierwszy i musiałem poświęcić trochę czasu na wyszukiwanie w Google, aby dowiedzieć się, czy naprawdę są dokładnie takie same.
źródło
string.Empty
? Czy wiesz, jaki""
był pierwszy raz?Ten temat jest dość stary i długi, więc przepraszam, jeśli takie zachowanie zostało wspomniane gdzie indziej. (I wskaż mi odpowiedź na to pytanie)
Znalazłem różnicę w zachowaniu kompilatora, jeśli używasz
string.Empty
lub cudzysłowu. Różnica pokazuje się, jeśli nie używasz zmiennej łańcuchowej zainicjowanej ciągiem znaków. Puste lub z podwójnymi cudzysłowami.W przypadku inicjalizacji z
string.Empty
tym ostrzeżeniem kompilatoranigdy nie jest emitowany, podczas gdy w przypadku inicjowania podwójnymi cudzysłowami pojawia się oczekiwany komunikat.
To zachowanie wyjaśniono w artykule Connect pod tym linkiem: https://connect.microsoft.com/VisualStudio/feedback/details/799810/c-warning-cs0219-not-reported-when-assign-non-constant-value
Zasadniczo, jeśli dobrze to zrozumiem, chcą pozwolić programistowi ustawić zmienną z wartością zwracaną funkcji do celów debugowania bez zawracania mu głowy ostrzeżeniem, a zatem ograniczają ostrzeżenie tylko w przypadku kosztownych przypisań i łańcucha. Puste nie jest stałą, ale polem.
źródło
var unused = "literal";
kompilator może całkowicie zoptymalizować (usunąć) deklarację . Nie może powodować żadnych skutków ubocznych. Z drugiej stronyvar unused = MyClass.Member;
nie można go całkowicie usunąć. To dlatego, że czytanieMember
może mieć skutki uboczne. JeśliMember
jest to właściwość statyczna zget
akcesorium, jasne jest, że połączenie z modułem pobierającym musi zostać zachowane. Ale nawet jeśliMember
jest to pole statyczne, może wystąpić efekt uboczny, który może uruchomić konstruktor statyczny. Jasne, że taki sposób kodowania byłby zły . Ale potrzebujesz manekina do czytaniaMember
.Ten bardzo prosty test wykonałem przy użyciu następującej metody w aplikacji konsolowej:
To wyraźnie sugeruje, że wszystkie trzy zmienne mianowicie
str1
,str2
istr3
chociaż są inicjowane przy użyciu innej składni, wskazują dokładnie ten sam obiekt (o zerowej długości) w pamięci. Test wykonałem w aplikacji konsoli .NET 4.5. Więc wewnętrznie nie mają różnicy, a wszystko sprowadza się do wygody, której chcesz użyć jako programisty. To zachowanie klasy ciągów jest znane jako internowanie ciągów w .NET. Eric Lippert ma bardzo ładny blog tutaj opisujący tę koncepcję.źródło
Dowolne z powyższych.
Jest wiele lepszych rzeczy do pontyfikatu. Jak na przykład kolor kory najlepiej pasuje do drzewa, myślę, że jest niejasny brąz z odcieniami mchu cielęcego.
źródło
Zdecydowanie wolę String.Empty, oprócz innych powodów, aby upewnić się, że wiesz, co to jest i że nie usunąłeś przypadkowo treści, ale przede wszystkim w celu internacjonalizacji. Jeśli widzę ciąg znaków w cudzysłowie, zawsze muszę się zastanawiać, czy jest to nowy kod i należy go umieścić w tabeli ciągów. Więc za każdym razem, gdy kod jest zmieniany / sprawdzany, musisz szukać „czegoś w cudzysłowach” i tak, możesz odfiltrować puste ciągi znaków, ale mówię ludziom, że dobrą praktyką jest, aby nigdy nie wstawiać ciągów znaków w cudzysłowie, chyba że wiesz, że nie zostanie ono zlokalizowane .
źródło
Nikt nie wspominał, że w VisualStudio String jest kodowany kolorem inaczej niż string. Co jest ważne dla czytelności. Również małe litery są zwykle używane dla zmiennych i typów, nie jest to wielka sprawa, ale String.Empty jest stałą, a nie zmienną ani typem.
źródło
string
jest synonimemSystem.String
typu, są identyczne.Wartości są również identyczne:
string.Empty == String.Empty == ""
Nie chciałbym używać stałej znaków „” w kodzie, raczej
string.Empty
lubString.Empty
- łatwiej zobaczyć co programista miał na myśli.Pomiędzy
string
i bardziejString
lubię małe literystring
tylko dlatego, że pracowałem z Delphi przez wiele lat, a styl Delphi jest pisany małymi literamistring
.Więc gdybym był twoim szefem, pisałbyś
string.Empty
źródło
Chciałbym sprzyjać
string.Empty
nadString.Empty
dlatego można go używać bez konieczności obejmująusing System;
w pliku.Jeśli chodzi o zbieranie
""
ciągustring.Empty
jest to osobiste preferencje i powinny być podejmowane przez zespół.źródło
string.Empty
stałej bez importowaniausing System
przestrzeni nazw - słowa kluczowe w C # po prostu przekonwertuj na ich w pełni kwalifikowaną nazwę, która obejmuje również przestrzeń nazw, zanim zostanie zapisana jako MSIL na wyjściu * .dll lub *. plik exe. Tak skuteczniestring.Empty
zostaje zapisanySystem.String.Empty
przez kompilator jak w MSIL. A ponieważ już wiesz, że jeśli podasz pełną nazwę typu, możesz pominąć importowanie przestrzeni nazw u góry pliku kodu.Nie robię różnicy. Ten ostatni jest jednak najszybszy do wpisania :)
źródło
To nie ma znaczenia - są dokładnie takie same. Najważniejsze jest jednak, abyś był konsekwentny
ps Cały czas walczę z tego rodzaju „co jest właściwe”.
źródło
Jest to całkowicie preferencja stylu kodu, rób, jak .NET obsługuje ciągi znaków. Oto moje opinie :)
Przy dostępie do statycznych metod, właściwości i pól zawsze używać nazw BCL Typ:
String.Empty
lubInt32.TryParse(...)
lubDouble.Epsilon
Zawsze używam słów kluczowych C # przy deklarowaniu nowych instancji:
int i = 0;
lubstring foo = "bar";
Rzadko używam niezadeklarowanych literałów łańcuchowych, ponieważ lubię mieć możliwość skanowania kodu w celu połączenia ich w nazwane stałe wielokrotnego użytku. Kompilator i tak zastępuje stałe literałami, więc jest to raczej sposób na uniknięcie magicznych ciągów / liczb i nadanie im trochę więcej znaczenia dzięki nazwie. Plus zmiana wartości jest łatwiejsza.
źródło
Używam trzeciego, ale z pozostałych dwóch pierwszy wydaje się mniej dziwny. string jest aliasem dla String, ale odczuwanie ich w zadaniu jest oderwane.
źródło
Każde z dwóch pierwszych byłoby dla mnie do zaakceptowania. Unikałbym tego ostatniego, ponieważ stosunkowo łatwo jest wprowadzić błąd, umieszczając odstęp między cudzysłowami. Ten konkretny błąd byłby trudny do znalezienia przez obserwację. Zakładając brak literówek, wszystkie są semantycznie równoważne.
[EDYTOWAĆ]
Ponadto, warto zawsze użyć jednej
string
lubString
dla spójności, ale to tylko moje zdanie.źródło
Osobiście byłem świadkiem „” powodujących (niewielkie) problemy dwukrotnie. Kiedyś był to błąd młodszego programisty, który był nowy w programowaniu zespołowym, a drugi to zwykła literówka, ale faktem jest ciąg znaków. Puste uniknęłoby obu problemów.
Tak, jest to w dużej mierze wezwanie do osądu, ale gdy język daje wiele sposobów robienia rzeczy, zwykle skłaniam się ku temu, który ma największy nadzór kompilatora i najsilniejsze wymuszanie czasu kompilacji. To nie jest „”. Chodzi o wyrażanie konkretnych intencji.
Jeśli wpiszesz string.EMpty lub Strng.Empty, kompilator poinformuje cię, że zrobiłeś to źle. Natychmiast. Po prostu się nie skompiluje. Jako programista powołujesz się na konkretną intencję, że kompilator (lub inny programista) nie może w żaden sposób źle interpretować, a gdy zrobisz to źle, nie możesz stworzyć błędu.
Jeśli wpiszesz „”, gdy masz na myśli „” lub odwrotnie, kompilator z radością zrobi to, co mu kazałeś. Inny programista może, ale nie musi, poznać twoją konkretną intencję. Błąd został utworzony.
Na długo przed string.Empty był rzeczą, której użyłem standardowej biblioteki, która zdefiniowała stałą EMPTY_STRING. Nadal używamy tej stałej w instrukcjach case, w których string.Empty jest niedozwolone.
O ile to możliwe, włącz kompilator, aby działał dla Ciebie i wyeliminuj możliwość błędu ludzkiego, bez względu na to, jak mały. IMO przebija „czytelność”, jak cytowali inni.
Specyfika i wymuszanie czasu kompilacji. To jest na obiad.
źródło
Używam „”, ponieważ w moim kodzie będzie miał wyraźnie żółty kolor ... z jakiegoś powodu String.Empty jest cały biały w moim motywie Visual Studio Code. I uważam, że to dla mnie najważniejsze.
źródło
Kompilator powinien uczynić je takimi samymi na dłuższą metę. Wybierz standard, aby kod był łatwy do odczytania i trzymaj się go.
źródło
Właśnie patrzyłem na jakiś kod i to pytanie przyszło mi do głowy, które czytałem już jakiś czas. Z pewnością jest to kwestia czytelności.
Rozważ następujący kod C # ...
vs
Osobiście uważam to drugie za mniej dwuznaczne i łatwiejsze do odczytania.
Jak zauważyli inni, rzeczywiste różnice są znikome.
źródło
Myślę, że to drugie jest „właściwe”, ale szczerze mówiąc, nie sądzę, żeby miało to znaczenie. Kompilator powinien być wystarczająco inteligentny, aby skompilować dowolny z tych dokładnie do tego samego kodu bajtowego. Sam używam „”.
źródło
Chociaż różnica jest bardzo, BARDZO mała, różnica wciąż istnieje.
1) „” tworzy obiekt, a String.Empty nie. Ale ten obiekt zostanie utworzony jeden raz i będzie później przywoływany z puli ciągów, jeśli masz inny kod w kodzie.
2) Ciąg znaków i ciąg znaków są takie same, ale zalecałbym użycie String.Empty (jak również String.Format, String.Copy itp.), Ponieważ notacja kropkowa wskazuje klasę, a nie operator, a klasa zaczynająca się od dużej litery jest zgodna z Standardy kodowania C #.
źródło
Na http://blogs.msdn.com/b/brada/archive/2003/04/22/49997.aspx :
źródło
Pusty ciąg jest jak pusty zestaw, po prostu nazwa, którą wszyscy używają do wywołania
""
. Również w językach formalnych ciągi utworzone z alfabetu o zerowej długości są nazywane ciągiem pustym. Zarówno zestaw, jak i łańcuch mają dla niego specjalny symbol. Pusty ciąg: ε i pusty zestaw: ∅. Jeśli chcesz porozmawiać o tym łańcuchu o zerowej długości, nazwiesz go pustym ciągiem, aby wszyscy wiedzieli dokładnie, o czym mówisz. Teraz, jeśli nazwiesz go pustym ciągiem, dlaczego nie użyćstring.Empty
w kodzie, jego zamiary są wyraźne. Minusem jest to, że nie jest stała i dlatego nie jest dostępna wszędzie, jak w atrybutach. (Z pewnych przyczyn technicznych nie jest stała, zobacz źródło odniesienia).źródło
Wolę,
""
ponieważ jest krótszy iString.Empty
rozwiązuje problem, który nie istnieje.źródło