@ORMapper, ale faktem jest, że stringjest to leksykalna konstrukcja gramatyki C #, podczas gdy System.Stringjest tylko typem. Bez względu na jakąkolwiek wyraźną różnicę wymienioną w jakiejkolwiek specyfikacji, nadal istnieje ta domniemana różnica, którą można przyjąć z pewną dwuznacznością. Sam język musi obsługiwać stringw taki sposób, aby implementacja nie była (całkiem) tak zobowiązana do rozważenia dla konkretnej klasy w BCL.
Kirk Woll,
106
@KirkWoll: Zgodnie ze specyfikacją języka, sam język musi uważać stringsię za dokładnie taki sam jak typ BCL System.String, nic więcej. To wcale nie jest dwuznaczne. Oczywiście, możesz zaimplementować własny kompilator, używając gramatyki C #, i użyć wszystkich znalezionych tokenów do czegoś dowolnego, niezwiązanego z tym, co jest zdefiniowane w specyfikacji języka C #. Jednak wynikowy język byłby tylko podobny do C #, nie można go uznać za C #.
LUB Mapper
88
Możesz używać stringbez dyrektywy użycia dla Systemu. Nie możesz tego zrobić String.
Wilsu
14
Dla kogoś pochodzącego z Algolu i Fortranu ta dyskusja pokazuje, że coś jest nie tak string. Należy go skracać System.String, ale jako alias wydaje się całkiem podobny, ale nie dokładnie to samo. Po kilku latach C #, choć powiedziałbym, że jest bezpieczny po prostu użyć string, a string.Format()nie martwić System.String.
Roland
8
@Sangeeta Co mówisz? System.StringKlasa nadal istnieje, a stringsłowo kluczowe jest nadal aliasem dla niego. Tak jak System.Int32i int. Są dosłownie tym samym.
Jeśli zdecydujesz się użyć StyleCop i postępujesz zgodnie z tym, powiesz, aby użyć typów specyficznych dla języka. Więc dla C # będziesz miał ciąg (zamiast Ciąg), int (zamiast Int32), pływak (zamiast Pojedynczy) - stylecop.soyuz5.com/SA1121.html
Dominic Zukiewicz
144
Zawsze używam aliasów, ponieważ zakładałem, że któregoś dnia może się to przydać, ponieważ działają one jako abstrakcja, dlatego mogą mieć zmienione implementacje bez mojej wiedzy.
Rob
37
Visual Studio 2015 mówi, że String.Format należy zmienić na string.Format, więc myślę, że Microsoft idzie w tym kierunku. Zawsze używałem również String do metod statycznych.
Sami Kuhmonen,
32
Po ich przeczytaniu zauważyłem, że kilka komentarzy jest po prostu niepoprawnych. @ DRAirey1 Z czasem przekonasz się, że stary sposób jest nadal najlepszy, jeśli wątpisz, to odważę się napisać kod C # bez użycia programu Visual Studio. Jest to praktycznie niemożliwe i sytuacja, która pojawia się od czasu do czasu w pracach programistycznych. @Vlad Nie musisz niczego importować, aby użyć String. @Abhi Twój komentarz jest bezcelowy i równie prawdziwy dla string.Format(). @KlitosG Nie, to nie jest prawda. Wszystkie działają dokładnie tak samo.
krowe2
46
Czy możesz dodać uwagę, że tak naprawdę jest różnica? Na przykład: nameof(string)nie będzie kompilować, ale nameof(String)będzie.
Jeroen Vannevel
3439
Dla kompletności, oto zrzut mózgu powiązanych informacji ...
Jak zauważyli inni, stringjest to pseudonim System.String. Kompilują się do tego samego kodu, więc w czasie wykonywania nie ma żadnej różnicy. To tylko jeden z aliasów w C #. Pełna lista to:
Oprócz stringi objectaliasy mają wszystkie typy wartości. decimaljest typem wartości, ale nie pierwotnym typem w CLR. Jedynym prymitywnym typem, który nie ma aliasu, jest System.IntPtr.
W specyfikacji aliasy typu wartości są znane jako „typy proste”. Literały mogą być użyte dla stałych wartości każdego prostego typu; żadne inne typy wartości nie mają dosłownych postaci. (Porównaj to z VB, który pozwala na DateTimeliterały i ma też alias.)
Jest jeszcze jedna okoliczność, w której ma używać aliasów: kiedy wyraźnie określający typ podstawowy enum jest. Na przykład:
To tylko kwestia sposobu spec definiuje enum deklaracji - część po dwukropku musi być integralną typu produkcję, która jest jednym wyrazem sbyte, byte, short, ushort, int, uint, long, ulong, char... w przeciwieństwie do typu produkcji, jak używane na przykład w deklaracjach zmiennych. Nie wskazuje to na żadną inną różnicę.
Wreszcie, jeśli chodzi o użycie: osobiście używam aliasów wszędzie do implementacji, ale typ CLR dla dowolnych interfejsów API. Naprawdę nie ma to większego znaczenia, którego używasz pod względem implementacji - spójność w zespole jest miła, ale nikogo to nie obchodzi. Z drugiej strony naprawdę ważne jest, aby odwoływać się do typu w interfejsie API, robiąc to w sposób neutralny językowo. Wywołana metoda ReadInt32jest jednoznaczna, podczas gdy nazwana metoda ReadIntwymaga interpretacji. Dzwoniący może na przykład używać języka, który definiuje intalias Int16. Projektanci .NET Framework podążały tego wzoru, dobre przykłady bycia w BitConverter, BinaryReaderi Convertklas.
Interesująca jest sytuacja dziedziczenia z wyliczeniem. Czy możesz wskazać w dokumentacji, dlaczego alias musi być używany do wyliczeń? Czy to znany błąd?
JaredPar
149
Znajduje się w sekcji 14.1 specyfikacji (nie mogę tutaj łatwo cytować, ponieważ jest za długi). Nie wyraźnie powiedzieć, że musisz użyć aliasu, ale aliasy są rodzajem traktowane jako własnych typów. To wszystko jest trochę dziwne.
Jon Skeet,
32
@PiPeep to, co jest bardziej zdumiewające niż duża liczba głosów pozytywnych, to oszałamiająca niska liczba głosów negatywnych (weź pod uwagę, że 5 pierwszych postów ma w sumie ponad 2000 głosów pozytywnych, a jednak tylko 1 głosowanie wśród nich wszystkich). Zwłaszcza jeśli weźmiesz pod uwagę fakt, że w każdej społeczności zawsze są „hejterzy”, naprawdę uważam to za po prostu niesamowite.
corsiKa
40
Jedną interesującą różnicą między stringi Stringjest to, że string' is a keyword in c#, so you can not use it as a variable name.For Ex: ciąg znaków = "hi"; //compiler error, but String String = "hi"; `jest dopuszczalne, podobnie jak Stringidentyfikator, a nie słowo kluczowe.
Sanjeev Rai
33
@SanjeevRai: Tak. Możesz użyć @stringdo utworzenia identyfikatora, który kończy się tak, stringjakby. To rodzaj mechanizmu ucieczki.
Jon Skeet
715
Stringoznacza System.Stringi jest to .NET Framework. stringto alias w języku C # dla System.String. Oba są kompilowane System.Stringw języku IL (Intermediate Language), więc nie ma różnicy. Wybierz, co lubisz i używaj tego. Jeśli kodujesz w języku C #, wolałbym, stringponieważ jest to alias typu C # i dobrze znany przez programistów C #.
Mogę powiedzieć to samo o ( int, System.Int32) itp.
`Jeśli kodujesz w C #, wolałbym napis, ponieważ jest to alias typu C # i dobrze znany programistom w C # - kiedy osoba C # nie zna frameworku .NET. +1, ponieważ myślę, że ogólnie jest to najlepsza odpowiedź, ale punkt, o którym wspominam, wydaje się dziwny.
MyDaftQuestions
4
Osobiście wolę używać „Int32”, ponieważ od razu pokazuje zakres wartości. Wyobraź sobie, że zaktualizowali typ „int” w późniejszych systemach o wyższych bitach. „int” in c jest najwyraźniej postrzegane jako „typ liczby całkowitej, z którym procesor docelowy najbardziej efektywnie pracuje” , i zdefiniowany jako „co najmniej 16 bitowy”. Wolę przewidywalną spójność tam, dziękuję bardzo.
Nyerguds
2
@MyDaftQuestions Zgadzam się. Jeśli cokolwiek miałoby sens konsekwentne używanie typów .net, ponieważ są one ignorantami językowymi, a typ jest oczywisty, niezależny od jakiegokolwiek języka (czy znam wszystkie osobliwości F # lub VB?).
Peter - Przywróć Monikę
5
@Nyerguds Istnieją dwa powody, aby po prostu się o to nie martwić. Jednym z nich jest to, że intjest zdefiniowany w specyfikacji języka C # jako 32-bitowa liczba całkowita bez względu na sprzęt. C #, pomimo wspólnego dziedzictwa w mgiełce czasu, tak naprawdę nie jest C. Zmiana intna 64-bitową liczbę całkowitą byłaby przełomową zmianą w specyfikacji i języku. Wymagałoby to również przedefiniowania long, ponieważ longobecnie jest to 64-bitowa liczba całkowita. Drugi powód, dla którego nie należy się martwić, jest nieistotny, ponieważ typy nigdy się nie zmienią, ale .NET jest wystarczająco abstrakcyjny, że w 99% przypadków nie musisz o tym myśleć. ;-)
Craig
5
@Craig wbijam na części starych formatami gier, gdzie nie trzeba myśleć o tym cały czas, choć. A następnie przy użyciu Int16, Int32i Int64to dużo bardziej przejrzyste w kodzie niż przy użyciu raczej nondescriptive short, intilong
Nyerguds
504
Najlepsza odpowiedź, jaką kiedykolwiek słyszałem o używaniu podanych typów aliasów w C #, pochodzi od Jeffreya Richtera w jego książce CLR Via C # . Oto jego 3 powody:
Widziałem wielu deweloperów zdezorientowany, nie wiedząc, czy użyć ciąg lub ciąg w kodzie. Ponieważ w języku C # ciąg (słowo kluczowe) jest dokładnie odwzorowany na System.String (typ FCL), nie ma różnicy i można go użyć.
W języku C # długie mapy na System.Int64 , ale w innym języku programowania, długie mogą być mapowane na Int16 lub Int32 . W rzeczywistości C ++ / CLI faktycznie traktuje długo jak Int32 . Ktoś czytający kod źródłowy w jednym języku mógłby łatwo błędnie zinterpretować intencję kodu, gdyby był przyzwyczajony do programowania w innym języku programowania. W rzeczywistości większość języków nie traktuje długo jako słowa kluczowego i nie skompiluje kodu, który go używa.
FCL ma wiele metod, które mają nazwy typów jako część nazw metod. Na przykład typ BinaryReader oferuje metody takie jak ReadBoolean , ReadInt32 , ReadSingle itp., A typ System.Convert oferuje metody takie jak ToBoolean , ToInt32 , ToSingle i tak dalej. Chociaż napisanie następującego kodu jest legalne, wiersz z float wydaje mi się bardzo nienaturalny i nie jest oczywiste, czy wiersz jest poprawny:
BinaryReader br =newBinaryReader(...);float val = br.ReadSingle();// OK, but feels unnaturalSingle val = br.ReadSingle();// OK and feels good
Więc masz to. Myślę, że to są naprawdę dobre punkty. Nie używam jednak rad Jeffreya we własnym kodzie. Być może jestem zbyt utknięty w moim świecie C #, ale w końcu staram się, aby mój kod wyglądał jak kod frameworka.
Drugi punkt brzmi rzeczywiście jak z jakiegoś powodu nie do użytku string, intitp
MauganRa
15
@MauganRa I tak powinno być, autor książki wymienia te powody, dla których nie używa aliasów.
tomi.lee.jones
31
„Jeśli ktoś czyta kod źródłowy C #, powinien interpretować długo zgodnie ze specyfikacją języka, a nie inną specyfikacją języków”. To całkowicie mija się z celem. Nie chodzi o to, że ktoś zamierza błędnie interpretować kod, po prostu mózg może łatwo wyciągnąć błędne wnioski, gdy typ ma inne znaczenie niż to, co programista widzi na co dzień w innym kontekście. Wszyscy popełniamy błędy; użycie jawnie nazwanych typów zmniejsza prawdopodobieństwo tych błędów.
Darryl
10
+ Te powody podsumowują moje uczucia w tej sprawie. Kiedy po raz pierwszy zacząłem pisać w języku C # (pochodzącym z Java / C ++ / C), myślałem, że aliasy były brzydkie. Nadal tak się czuję, niestety większość świata nie zgadza się ze mną lub ich to nie obchodzi, dlatego używaj małych liter.
gusgorman
8
@ jinzai pytanie dotyczy C #, w którym longjest zdefiniowana jako 64-bitowa liczba całkowita ze znakiem, niezależnie od platformy lub kompilatora. Tak więc w niektórych przypadkach co najmniej, tak, to nie zależą od języka.
phoog
455
stringjest zastrzeżonym słowem, ale Stringjest tylko nazwą klasy. Oznacza to, że sam stringnie może być użyty jako nazwa zmiennej.
Jeśli z jakiegoś powodu chcesz zmiennej o nazwie string , zobaczysz tylko pierwszą z tych kompilacji:
Pamiętaj, że dzwonienie do lokalnego @stringjest naprawdę bezcelowe, ponieważ nazwy mieszkańców są obecne tylko w PDB. Równie dobrze można to nazwać _stringczy coś takiego. Bardziej sensowne są rzeczy, które mają nazwy dostępne poprzez odbicie, w miejscu, gdzie @stringbyłoby imię członka "string".
Roman Starkov,
25
Należy również pamiętać o używaniu słowa zastrzeżonego, ponieważ nazwa zmiennej jest rażąco nieelegancka.
Elton
7
OP nie chce używać Ciągu lub Ciągu jako nazwy zmiennej. Poprosili o wyjaśnienie różnicy między tymi typami . Twoja odpowiedź służy jedynie do dodania więcej zamieszania IMO
Matt Wilko
1
@craig, jeśli piszesz oprogramowanie, aby nauczyć ludzi, jak wiązać węzły?
Simon_Weaver,
5
@Simon_Weaver węzły w ciągach? haha, miło. :-) Oczywiście możesz wybrać alternatywną nazwę, na przykład wątek. Zaczekaj chwilę ... D'oh!
Craig,
391
Jest jeszcze jedna różnica - nie można używać Stringbez using System;wcześniej.
domyślnie większość ludzi dodaje to w jakikolwiek sposób na górze pliku. VS robi to domyślnie w większości przypadków nie wszystkich!
IbrarMumtaz,
9
Domyślnie dodaję tylko usingwymagane przeze mnie instrukcje i jawnie usuwam wszystko, czego nie potrzebuję. Power Productivity Tools> „[x] Usuń i sformatuj zastosowania przy zapisywaniu”
JMD
2
@JMD Zmodyfikowałem plik szablonu .cs, więc nie ma w nim nawet żadnych instrukcji używania! Zmieniłem również szablon klasy na internal sealed.
ErikE
@JMD Nienawidzę tej funkcji. Czasami wprowadza zmiany w nietkniętych plikach, co utrudnia sprawdzenie, jakie rzeczywiste zmiany zawiera zestaw zmian. Oczywiście zazwyczaj usuwam „za pomocą spamu”, ale tylko aktywnie, nie automatycznie.
mg30rg
Może tak być w przypadku C #, ale nie wszystkich języków .NET. (Powershell domyślnie importuje przestrzeń nazw Systemu.)
FSCKur
311
Zostało to omówione powyżej; nie możesz jednak używać stringw refleksji; musisz użyć String.
Nie rozumiem, co oznacza ta odpowiedź i dlaczego została wzięta pod uwagę. Możesz użyć typeof(string)w refleksji. Przykład pierwszy: if (someMethodInfo.ReturnType == typeof(string)) { ... }Przykład drugi: var p = typeof(string).GetProperty("FirstChar", BindingFlags.NonPublic | BindingFlags.Instance);Gdzie musisz go użyć String, a nie string? Jeśli spróbujesz czegoś takiego jak Type.GetType("String")lub Type.GetType("string"), żadna nie znajdzie klasy, ponieważ brakuje przestrzeni nazw. Jeśli z jakiegoś głupiego powodu porównujesz .Nametyp z "string"rozróżnianiem wielkości liter, masz rację.
Jeppe Stig Nielsen
256
System.Stringjest klasą ciągów .NET - w C # stringjest aliasem System.String- więc w użyciu są takie same.
Jeśli chodzi o wytyczne, nie ugrzęznę zbytnio i po prostu używam tego, na co masz ochotę - w życiu są ważniejsze rzeczy, a kod i tak będzie taki sam.
Jeśli znajdziecie się systemy, w których konieczne jest budynek określić wielkość liczb całkowitych, którego używasz, a więc mają tendencję do używania Int16, Int32, UInt16, UInt32itd. To może wyglądać bardziej naturalnie używać String- i podczas poruszania się między różnymi językami .net to może uczynić rzeczy bardziej zrozumiałymi - w przeciwnym razie użyłbym łańcucha i int.
Wybierz jeden i bądź konsekwentny. Jeśli pracujesz gdzieś w stylu domu, użyj tego.
Alan B
3
niestety styl jest osobistą preferencją i może być zbyt drogi, aby egzekwować w dużej bazie kodu w kilku zespołach bez dedykowanego właściciela kodu. zawsze są ważniejsze kwestie do załatwienia niż łańcuch zamiast łańcucha. co sprowadza nas z powrotem do „ważniejszych rzeczy w życiu”
aiodintsov
Jest to zdecydowanie preferencja; na przykład: Wolę używać short, int, ushort, uintzamiast Int16, itd. Głównie dlatego, że jest to jak dowiedziałem. To prawda, że Int16łatwiej jest od razu zrozumieć dla osób z mniejszym doświadczeniem. +1 ode mnie!
Emma
210
Wolę .NETtypy pisane wielkimi literami (zamiast aliasów) ze względu na formatowanie. Te .NETtypy są barwione takie same jak innych typów obiektów (typy wartości są odpowiednie obiekty, mimo wszystko).
Słowa kluczowe warunkowe i kontrolne (jak if, switchi return) są pisane małymi literami i mają kolor ciemnoniebieski (domyślnie). I wolałbym nie mieć niezgodności w użyciu i formacie.
Czy piszesz także kod w rodzaju: Int32 i = 1; Zamiast int i = 1; ? Wydaje się niespójne, aby nie używać aliasu ciągu, gdy jest on dostępny.
bytedev
29
@nashwan: właściwie tak, używam Int32 i=1;zamiast tego int i = 1; uważam, że ten pierwszy jest bardziej czytelny pod względem moich zamiarów: mianowicie, że chcę 32-bitową liczbę całkowitą ze znakiem.
NotMe
5
Cóż, myślę, że wszystko zależy od tego, czy programista myśli, że piszą kod C # (ciąg) czy kod .NET (ciąg). Osobiście przede wszystkim myślę, że piszę w C # (i to C # używa .NET).
bytedev
7
@Alex: miałem na myśli po prostu to, że wolę być bardzo specyficzny w kodowaniu, aby usunąć dwuznaczność.
NotMe
22
Na absolutnym drugim końcu spektrum prawie zawsze używamvar
tic
192
stringi Stringsą identyczne pod każdym względem (oprócz wielkich liter „S”). Tak czy inaczej, nie ma to wpływu na wydajność.
Małe litery stringsą preferowane w większości projektów ze względu na wyróżnianie składni
Jeffrey Richter zaleca stosowanie typu CLR we wszystkich przypadkach (CLR przez C #), aby uniknąć dokładnie tego rodzaju zamieszania, które ma tutaj miejsce.
Josh
Oczywiste jest, że niezależnie od tego, czy użyjesz S, czy s, spowoduje to powstanie tych pytań, więc zignoruj Richtera. ;)
Brad Wilson
Richter oznaczał, że łańcuch nie powinien być opcją - Microsoft nie powinien mieć go w języku. Nie możesz głosować za Richerem - on jest legendą! :)
Joe Ratzer
1
Zgadzam się, że może być lepiej, aby nie mieć aliasy w ogóle. Ale biorąc pod uwagę, że je mamy, myślę, że można z nich korzystać (ale nie w nazwach metod itp.)
Jon Skeet,
10
„ciąg” nie jest tym samym, co „ciąg”. To znaczy „System.String”. Więc jeśli używasz „String”, musisz wpisać „using System”, aby dołączyć przestrzeń nazw
ThiagoAlves
185
C # to język używany razem z CLR.
string jest typem w C #.
System.String jest typem w CLR.
Gdy użyjesz C # wraz z CLR stringzostanie zamapowany na System.String.
Teoretycznie można zaimplementować kompilator C #, który wygenerował kod bajtowy Java. Rozsądnym Realizacja tego kompilatora najprawdopodobniej na mapie string, aby java.lang.Stringw celu współdziałania z biblioteki uruchomieniowym Java.
stringnie jest typem w C #; jest to słowo zastrzeżone, które odwzorowuje na typ w CLR.
CesarGon
@CesarGon: Zgodnie z ECMA-334, sekcja 8.2.1: „C # zapewnia zestaw predefiniowanych typów [...] Predefiniowanymi typami referencyjnymi są obiekt i ciąg znaków.”
Rasmus Faber
10
Zgodnie z ECMA-334, sekcja 9.4.3, „ciąg znaków” jest słowem kluczowym. :-) Zgadzam się z tobą, że „ciąg znaków” jest typem, jeśli skupiasz się na semantyce, ale powiedziałbym, że jest słowem kluczowym (tj. Słowem zastrzeżonym), jeśli skupiasz się na składni. Standard popiera oba punkty widzenia (być może zbyt dwuznacznie!). Dla mnie OP dotyczy składni, więc skupiam się na składni, kiedy patrzę na odpowiedzi, ale rozumiem również twój punkt widzenia. Co więcej, twoja odpowiedź w obecnej postaci może być interpretowana w ten sposób, że istnieją dwa różne typy: łańcuch i łańcuch, jeśli tak nie jest. Jedno jest odwzorowaniem na drugie.
CesarGon
Wyjaśnijmy to sobie. „ciąg” jest zastrzeżonym aliasem. To nie jest prawdziwy typ danych. Jest to coś, co wskazuje na coś innego. Możesz usunąć wszystkie te aliasy (lub po prostu nigdy ich nie używać) i mieć doskonale dobry język programowania.
Quarkly
168
Ten film na YouTube pokazuje praktycznie, jak się różnią.
Ale teraz długa odpowiedź tekstowa.
Kiedy mówimy o .NETistnieją dwie różne rzeczy jeden jest .NETramowy i drugi są języki ( C#, VB.NETetc), które wykorzystują te ramy.
„ System.String„ aka ”„ String ”(wielkie„ S ”) jest .NETramowym typem danych, a„ string ”to C#typ danych.
W skrócie „String” to alias (to samo, co nazywa się różnymi nazwami) „string”. Tak więc technicznie obie poniższe instrukcje kodu dają to samo wyjście.
String s ="I am String";
lub
string s ="I am String";
W ten sam sposób istnieją aliasy dla innych typów danych c #, jak pokazano poniżej: -
Obiekt System.Object, string: System.String, bool: System.Booleanbajt: System.Byte, sbyte: System.SBytekrótka: System.Int16i tak dalej
Teraz pytanie za milion dolarów z punktu widzenia programisty Więc kiedy używać „String” i „string”?
Pierwszą rzeczą, aby uniknąć zamieszania, używaj jednego z nich konsekwentnie. Ale z punktu widzenia najlepszych praktyk, kiedy robisz deklarację zmiennej, dobrze jest używać „łańcucha” (małych „s”), a gdy używasz go jako nazwy klasy, preferowany jest „Łańcuch” (wielkie „S”).
W poniższym kodzie lewa strona jest deklaracją zmiennej i zadeklarowana za pomocą „łańcucha”. Po prawej stronie wywołujemy metodę, aby „String” był bardziej sensowny.
„W skrócie” String ”to alias (to samo, co nazywa się różnymi nazwami)„ string ””. To nie jest poprawne: alias to „ciąg”.
Xavier Egea
3
kiedy deklarujesz zmienną, dobrze jest użyć „łańcucha” (małych „s”), a gdy używasz go jako nazwy klasy, wtedy preferowany jest „Ciąg” (duże „S”). Ta konwencja wydaje się już nieaktualna: jeśli korzystasz z programu Visual Studio 2015 i spróbujesz go napisać String, zasugeruj, aby „uprościć kod”, przenosząc go do string...
Massimiliano Kraus,
165
Małe litery stringto pseudonim System.String. Są takie same w C#.
Jest to debata nad tym, czy należy użyć typów systemów ( System.Int32, System.Stringetc.) rodzaje lub C# aliases( int, stringitp). Osobiście uważam, że powinieneś skorzystać C# aliases, ale to tylko moje osobiste preferencje.
Na tym polega problem, nie są to aliasy „C #”, tylko aliasy „C”. W języku C # nie ma natywnego „łańcucha” ani „int”, tylko cukier syntaktyczny.
Quarkly
16
nie jestem pewien, skąd pochodzi „C”, ponieważ specyfikacja języka C # 5 brzmi „Łańcuch słów kluczowych jest po prostu aliasem dla predefiniowanej klasy System.String”. na stronie 85, pkt 4.2.4. Wszystkie języki wysokiego poziomu są składniowe w porównaniu do zestawów instrukcji procesora i kodu bajtowego.
aiodintsov
156
stringjest tylko pseudonimem dla System.String. Kompilator potraktuje je identycznie.
Jedyną praktyczną różnicą jest podświetlanie składni, o czym wspominasz, i że musisz pisać, using Systemjeśli używasz String.
using SystemPodczas używania musisz podać a String, w przeciwnym razie pojawi się następujący błąd:The type or namespace name 'String' could not be found (are you missing a using directive or an assembly reference?)
Ronald,
143
Oba są takie same. Ale z perspektywy wytycznych kodowania lepiej jest używać stringzamiast String. Tego właśnie używają programiści. np. zamiast używać Int32używamy intjako intalias doInt32
Jak mówią inni, są tacy sami. Zasady StyleCop domyślnie wymusi na użycie stringjako kodu C # stylu najlepszych praktyk, z wyjątkiem gdy przedstawieniu System.Stringfunkcje statyczne, takie jak String.Format, String.Join, String.Concatitp ...
Nie wiedziałem, że StyleCop oznaczy użycie String - z wyjątkiem metod statycznych. Myślę, że jest to świetne, ponieważ zawsze tak go używam: ciąg znaków do deklaracji typu i ciąg znaków, gdy uzyskuję dostęp do elementów statycznych.
Goyuix,
101
Nowa odpowiedź po 6 latach i 5 miesiącach (zwlekanie).
Chociaż stringjest zarezerwowanym słowem kluczowym C #, które zawsze ma stałe znaczenie, Stringjest zwykłym identyfikatorem, który może odnosić się do czegokolwiek. W zależności od elementów bieżącego typu bieżąca przestrzeń nazw oraz zastosowane usingdyrektywy i ich umiejscowienie Stringmogą być wartością lub typem innym niż global::System.String.
Podam dwa przykłady, w których usingdyrektywy nie pomogą .
Po pierwsze, kiedy Stringjest wartością bieżącego typu (lub zmiennej lokalnej):
classMySequence<TElement>{publicIEnumerable<TElement>String{get;set;}voidExample(){var test =String.Format("Hello {0}.",DateTime.Today.DayOfWeek);}}
Powyższe nie zostanie skompilowane, ponieważ IEnumerable<>nie ma wywołanego elementu niestatycznego Formati nie stosuje się żadnych metod rozszerzenia. W powyższym przypadku nadal może być możliwe użycie Stringw innych kontekstach, w których typ jest jedyną możliwością składniową. Na przykład String local = "Hi mum!";może być OK (w zależności od przestrzeni nazw i usingdyrektyw).
Gorzej: powiedzenie String.Concat(someSequence)prawdopodobnie (w zależności od usings) przejdzie na metodę rozszerzenia Linq Enumerable.Concat. Nie przejdzie do metody statycznej string.Concat.
Po drugie, kiedy Stringjest inny typ , zagnieżdżony w bieżącym typie:
Żadna instrukcja w Examplemetodzie się nie kompiluje. Tutaj Stringzawsze jest piano ciąg , MyPiano.String. Nie istnieje na nim żaden element członkowski ( staticani nie Formatjest on dziedziczony z jego klasy podstawowej). A wartości "Goodbye"nie można na nią przeliczyć.
Przypuszczam, że jestem diabelski, można: using String = System.Int32; using Int32 = System.String; a następnie policzyć błędy.
Steve
7
to jest poprawna odpowiedź. stringjest System.String. Stringmoże być cokolwiek.
Dave Cousineau,
Zgoda @DaveCousineau - o to chodzi w aliasie. Możesz utworzyć inny Stringtyp, który nie byłby ustawiony na obiekt System.String. Sprawdź: blog.paranoidcoding.com/2019/04/08/…
Kristopher
„Słowo kluczowe stringma konkretne znaczenie w języku C #. Jest to typ, System.Stringktóry istnieje w podstawowym zestawie wykonawczym. Środowisko wykonawcze w pełni rozumie ten typ i zapewnia możliwości, których twórcy oczekują stringsw .NET. Jego obecność jest tak ważna dla C #, że jeśli ten typ nie 't istnieje, kompilator zakończy działanie przed próbą nawet parsowania wiersza kodu. Stąd stringma precyzyjne, jednoznaczne znaczenie w kodzie C #. Identyfikator Stringnie ma jednak żadnego konkretnego znaczenia w C #. Jest to identyfikator, który przechodzi przez wszystkie reguły wyszukiwania nazw jako Widget, Studentitd ...”
W przeciwieństwie do tego, co wydaje się być powszechną praktyką wśród innych programistów, wolę bardziej Stringniż stringtylko po to, aby podkreślić fakt, że Stringjest to typ odniesienia, jak wspomniał Jon Skeet.
stringto alias (lub skrót) z System.String. To znaczy, pisząc na stringmyśli, mieliśmy na myśli System.String. Możesz przeczytać więcej na stronie think link: „string” to alias / stenografia System.String.
Chciałbym tylko dodać to do odpowiedzi lfousts z książki Ritchers:
Specyfikacja języka C # stanowi: „Ze względu na styl, użycie słowa kluczowego jest preferowane zamiast używania pełnej nazwy typu systemu”. Nie zgadzam się ze specyfikacją języka; Wolę używać nazw typów FCL i całkowicie unikać pierwotnych nazw typów. W rzeczywistości chciałbym, aby kompilatory nawet nie oferowały nazw typów pierwotnych i zmusiły programistów do używania zamiast nich nazw typów FCL. Oto moje powody:
Widziałem wielu deweloperów zdezorientowany, nie wiedząc, czy użyć ciąg
lub ciąg w kodzie. Ponieważ w łańcuchu C # (słowo kluczowe) mapuje się dokładnie na
System.String (typ FCL), nie ma żadnej różnicy i można go użyć. Podobnie słyszałem, jak niektórzy programiści mówili, że int reprezentuje 32-bitową liczbę całkowitą, gdy aplikacja działa w 32-bitowym systemie operacyjnym i że reprezentuje 64-bitową liczbę całkowitą, gdy aplikacja działa w 64-bitowym systemie operacyjnym. To stwierdzenie jest absolutnie fałszywe: w języku C # int zawsze mapuje na System.Int32 , a zatem reprezentuje 32-bitową liczbę całkowitą niezależnie od systemu operacyjnego, na którym działa kod. Jeśli programiści skorzystalibyInt32 w swoim kodzie, to potencjalne zamieszanie również zostaje wyeliminowane.
W języku C # długie mapy na System.Int64 , ale w innym języku programowania, długie
mogą być mapowane na Int16 lub Int32 . W rzeczywistości C ++ / CLI długo traktuje jak Int32 . Ktoś czytający kod źródłowy w jednym języku mógłby łatwo błędnie zinterpretować intencję kodu, gdyby był przyzwyczajony do programowania w innym języku programowania. W rzeczywistości większość języków nie traktuje długo jako słowa kluczowego i nie skompiluje kodu, który go używa.
FCL ma wiele metod, które mają nazwy typów jako część nazw metod. Na przykład typ BinaryReader oferuje metody takie jak ReadBoolean , ReadInt32 ,
ReadSingle itp., A typ System.Convert oferuje metody takie jak
ToBoolean , ToInt32 , ToSingle i tak dalej. Chociaż napisanie następującego kodu jest legalne, wiersz z float wydaje mi się bardzo nienaturalny i nie jest oczywiste, czy wiersz jest poprawny:
BinaryReader br =newBinaryReader(...);float val = br.ReadSingle();// OK, but feels unnaturalSingle val = br.ReadSingle();// OK and feels good
Wielu programistów używających wyłącznie języka C # ma tendencję do zapominania, że inne języki programowania mogą być używane przeciwko CLR, i dlatego z tego powodu do kodu biblioteki klas wkradają się organizmy C #. Na przykład Microsoft FCL jest prawie wyłącznie napisany w języku C # i deweloperów w zespole FCL teraz wprowadzono metody do biblioteki takiego jak
Array „s GetLongLength , która zwraca Int64 wartość, która jest długo w C #, ale nie w innych językach (takich jak C ++ / CLI). Innym przykładem jest System.Linq.Enumerable jest
LongCount metodą.
Nie otrzymałem jego opinii, zanim przeczytałem cały akapit.
String ( System.String) to klasa w bibliotece klas podstawowych. string (małe litery) to zarezerwowana praca w C #, która jest aliasem dla System.String. Int32 vs int jest podobną sytuacją Boolean vs. bool. Te słowa kluczowe specyficzne dla języka C # umożliwiają deklarowanie prymitywów w stylu podobnym do C.
Stringnie jest słowem kluczowym i może być używany jako identyfikator, natomiast stringjest słowem kluczowym i nie może być używany jako identyfikator. I z punktu widzenia funkcji oba są takie same.
To naprawdę kwestia konwencji. stringwygląda bardziej jak styl C / C ++. Ogólna konwencja polega na korzystaniu ze skrótów udostępnionych przez wybrany język (int / Int dla Int32). Dotyczy to również „obiektu” decimal.
Teoretycznie może to pomóc w przeniesieniu kodu do jakiegoś przyszłego standardu 64-bitowego, w którym może oznaczać „int” Int64, ale nie o to chodzi, i spodziewałbym się, że każdy kreator aktualizacji zmieni wszelkie intodniesienia do, Int32po prostu, aby był bezpieczny.
Spóźniam się na imprezę: używam typów CLR w 100% przypadków (cóż, z wyjątkiem sytuacji, gdy zmuszony jestem używać typu C #, ale nie pamiętam, kiedy to był ostatni raz).
Pierwotnie zacząłem robić to lata temu, zgodnie z książkami CLR autorstwa Ritchie. Miałem dla mnie sens, że wszystkie języki CLR ostatecznie muszą być w stanie obsługiwać zestaw typów CLR, więc użycie tych typów CLR zapewniło jaśniejszy i prawdopodobnie bardziej „wielokrotnego użytku” kod.
Teraz, gdy robię to od lat, jest to nawyk i podoba mi się ubarwienie, które VS pokazuje dla typów CLR.
Jedynym minusem jest to, że autouzupełnianie używa typu C #, więc kończę przepisywanie automatycznie generowanych typów w celu określenia typu CLR.
Również teraz, gdy widzę „int” lub „string”, wygląda mi to naprawdę źle, tak jak patrzę na kod C z 1970 roku.
W wersji 64-bitowej int odwzorowuje na System.Int64 (8 bajtów), w wersji 32-bitowej mapuje na System.Int32 (4 bajty)
Alex
1
IntPtr i UIntPtr to jedyne typy, które zmieniają rozmiar w zależności od platformy (pomijając rzeczywiste typy wskaźników, takie jak int*i typy złożone z [U] IntPtr lub rzeczywistych wskaźników).
Wszystkie predefiniowane typy są mapowane bezpośrednio na podstawowe typy .NET. Nazwy typu C # (ciąg znaków) są po prostu aliasami dla typów .NET (String lub System.String), więc używanie nazw .NET działa poprawnie składniowo, chociaż jest to odradzane. W programie C # powinieneś używać nazw C # zamiast nazw .NET.
Jedyną niewielką różnicą jest to, że jeśli używasz klasy String, musisz zaimportować przestrzeń nazw System na wierzchu pliku, podczas gdy nie musisz tego robić, używając słowa kluczowego string.
Uttam
Istnieją proste przypadki użycia, w których instrukcja równości zawiodłaby ... Na przykład zdefiniowanie typu wywołania typu String w przestrzeni nazw bla i zaimportowanie tej przestrzeni nazw do pliku, w którym działa instrukcja równości.
Ricka
40
Tak, to nie jest różnica między nimi, podobnie jak booli Boolean.
@JaredPar (twórca kompilatora C # i płodny użytkownik SO!) Napisał świetny post na blogu na ten temat. Myślę, że warto się tutaj podzielić. To miłe spojrzenie na nasz temat.
stringvs. Stringnie jest debatą stylową
[...]
Słowo kluczowe stringma konkretne znaczenie w języku C #. Jest to typ, System.Stringktóry istnieje w podstawowym zestawie wykonawczym. Środowisko wykonawcze w pełni rozumie ten typ i zapewnia możliwości, których twórcy oczekują od ciągów w .NET. Jego obecność jest tak ważna dla C #, że jeśli ten typ nie istnieje, kompilator zakończy działanie przed próbą nawet parsowania linii kodu. Stąd stringma precyzyjne, jednoznaczne znaczenie w kodzie C #.
Identyfikator Stringnie ma jednak konkretnego znaczenia w języku C #. Jest to identyfikator, który przechodzi przez wszystkie reguły wyszukiwania nazw jako Widget, Studentitp. Może wiązać się z łańcuchem lub z innym typem zestawu, którego cele mogą być zupełnie inne niż string. Co gorsza, można go zdefiniować w taki sposób, jak kod String s = "hello"; kontynuował kompilację.
classTricksterString{voidExample(){String s ="Hello World";// Okay but probably not what you expect.}}classString{publicstaticimplicitoperatorString(string s)=>null;}
Rzeczywiste znaczenie Stringzawsze będzie zależeć od rozpoznawania nazw. Oznacza to, że zależy to od wszystkich plików źródłowych w projekcie i wszystkich typów zdefiniowanych we wszystkich zestawach, do których istnieją odniesienia. Krótko mówiąc, potrzeba sporo kontekstu, aby wiedzieć, co to znaczy.
To prawda, że w zdecydowanej większości przypadków Stringi stringzwiąże się z tego samego typu. Ale używanie Stringnadal oznacza, że programiści pozostawiają swój program do interpretacji w miejscach, gdzie jest tylko jedna poprawna odpowiedź. Kiedy Stringwiąże się z niewłaściwym typem, może programistom debugować godzinami, zgłaszać błędy w zespole kompilatora i generalnie marnować czas, który można by zaoszczędzić, używając string.
Innym sposobem na zwizualizowanie różnicy jest użycie tej próbki:
string s1 =42;// Errors 100% of the time String s2 =42;// Might error, might not, depends on the code
Wielu będzie argumentować, że chociaż informacje te są technicznie dokładne, używanie Stringjest w porządku, ponieważ niezwykle rzadko podstawa kodu definiuje typ tej nazwy. Lub, gdy Stringjest zdefiniowany, jest to znak złej bazy kodu.
[...]
Zobaczysz, że Stringjest zdefiniowany dla szeregu całkowicie ważnych celów: pomocników refleksji, bibliotek serializacji, leksykonów, protokołów itp. Dla każdej z tych bibliotek Stringvs. stringma realne konsekwencje w zależności od tego, gdzie jest używany kod.
Więc pamiętaj, kiedy widzisz debatę Stringkontra vs. stringdotyczy semantyki, a nie stylu. Wybór ciągu nadaje wyraźne znaczenie twojej bazie kodu. Wybór Stringnie jest zły, ale pozostawia otwarte drzwi dla niespodzianek w przyszłości.
Uwaga: skopiowałem / wkleiłem większość postów na blogu z przyczyn archiwalnych. Ignoruję niektóre części, więc jeśli to możliwe , polecam pominąć i przeczytać post na blogu .
string
jest to leksykalna konstrukcja gramatyki C #, podczas gdySystem.String
jest tylko typem. Bez względu na jakąkolwiek wyraźną różnicę wymienioną w jakiejkolwiek specyfikacji, nadal istnieje ta domniemana różnica, którą można przyjąć z pewną dwuznacznością. Sam język musi obsługiwaćstring
w taki sposób, aby implementacja nie była (całkiem) tak zobowiązana do rozważenia dla konkretnej klasy w BCL.string
się za dokładnie taki sam jak typ BCLSystem.String
, nic więcej. To wcale nie jest dwuznaczne. Oczywiście, możesz zaimplementować własny kompilator, używając gramatyki C #, i użyć wszystkich znalezionych tokenów do czegoś dowolnego, niezwiązanego z tym, co jest zdefiniowane w specyfikacji języka C #. Jednak wynikowy język byłby tylko podobny do C #, nie można go uznać za C #.string
bez dyrektywy użycia dla Systemu. Nie możesz tego zrobićString
.string
. Należy go skracaćSystem.String
, ale jako alias wydaje się całkiem podobny, ale nie dokładnie to samo. Po kilku latach C #, choć powiedziałbym, że jest bezpieczny po prostu użyćstring
, astring.Format()
nie martwićSystem.String
.System.String
Klasa nadal istnieje, astring
słowo kluczowe jest nadal aliasem dla niego. Tak jakSystem.Int32
iint
. Są dosłownie tym samym.Odpowiedzi:
string
to alias w języku C # dlaSystem.String
.Więc technicznie nie ma różnicy. To jak
int
vs.System.Int32
.Jeśli chodzi o wytyczne, ogólnie zaleca się korzystanie z niego za
string
każdym razem, gdy odwołujesz się do obiektu.na przykład
Podobnie, myślę, że ogólnie zaleca się stosowanie,
String
jeśli chcesz odnieść się konkretnie do klasy.na przykład
Jest to styl, który Microsoft używa w swoich przykładach .
Wygląda na to, że wskazówki w tym obszarze mogły ulec zmianie, ponieważ StyleCop wymusza teraz stosowanie aliasów specyficznych dla języka C #.
źródło
string.Format()
. @KlitosG Nie, to nie jest prawda. Wszystkie działają dokładnie tak samo.nameof(string)
nie będzie kompilować, alenameof(String)
będzie.Dla kompletności, oto zrzut mózgu powiązanych informacji ...
Jak zauważyli inni,
string
jest to pseudonimSystem.String
. Kompilują się do tego samego kodu, więc w czasie wykonywania nie ma żadnej różnicy. To tylko jeden z aliasów w C #. Pełna lista to:Oprócz
string
iobject
aliasy mają wszystkie typy wartości.decimal
jest typem wartości, ale nie pierwotnym typem w CLR. Jedynym prymitywnym typem, który nie ma aliasu, jestSystem.IntPtr
.W specyfikacji aliasy typu wartości są znane jako „typy proste”. Literały mogą być użyte dla stałych wartości każdego prostego typu; żadne inne typy wartości nie mają dosłownych postaci. (Porównaj to z VB, który pozwala na
DateTime
literały i ma też alias.)Jest jeszcze jedna okoliczność, w której ma używać aliasów: kiedy wyraźnie określający typ podstawowy enum jest. Na przykład:
To tylko kwestia sposobu spec definiuje enum deklaracji - część po dwukropku musi być integralną typu produkcję, która jest jednym wyrazem
sbyte
,byte
,short
,ushort
,int
,uint
,long
,ulong
,char
... w przeciwieństwie do typu produkcji, jak używane na przykład w deklaracjach zmiennych. Nie wskazuje to na żadną inną różnicę.Wreszcie, jeśli chodzi o użycie: osobiście używam aliasów wszędzie do implementacji, ale typ CLR dla dowolnych interfejsów API. Naprawdę nie ma to większego znaczenia, którego używasz pod względem implementacji - spójność w zespole jest miła, ale nikogo to nie obchodzi. Z drugiej strony naprawdę ważne jest, aby odwoływać się do typu w interfejsie API, robiąc to w sposób neutralny językowo. Wywołana metoda
ReadInt32
jest jednoznaczna, podczas gdy nazwana metodaReadInt
wymaga interpretacji. Dzwoniący może na przykład używać języka, który definiujeint
aliasInt16
. Projektanci .NET Framework podążały tego wzoru, dobre przykłady bycia wBitConverter
,BinaryReader
iConvert
klas.źródło
string
iString
jest to, żestring' is a keyword in c#, so you can not use it as a variable name.For Ex:
ciąg znaków = "hi";//compiler error, but
String String = "hi"; `jest dopuszczalne, podobnie jakString
identyfikator, a nie słowo kluczowe.@string
do utworzenia identyfikatora, który kończy się tak,string
jakby. To rodzaj mechanizmu ucieczki.String
oznaczaSystem.String
i jest to .NET Framework.string
to alias w języku C # dlaSystem.String
. Oba są kompilowaneSystem.String
w języku IL (Intermediate Language), więc nie ma różnicy. Wybierz, co lubisz i używaj tego. Jeśli kodujesz w języku C #, wolałbym,string
ponieważ jest to alias typu C # i dobrze znany przez programistów C #.Mogę powiedzieć to samo o (
int
,System.Int32
) itp.źródło
int
jest zdefiniowany w specyfikacji języka C # jako 32-bitowa liczba całkowita bez względu na sprzęt. C #, pomimo wspólnego dziedzictwa w mgiełce czasu, tak naprawdę nie jest C. Zmianaint
na 64-bitową liczbę całkowitą byłaby przełomową zmianą w specyfikacji i języku. Wymagałoby to również przedefiniowanialong
, ponieważlong
obecnie jest to 64-bitowa liczba całkowita. Drugi powód, dla którego nie należy się martwić, jest nieistotny, ponieważ typy nigdy się nie zmienią, ale .NET jest wystarczająco abstrakcyjny, że w 99% przypadków nie musisz o tym myśleć. ;-)Int16
,Int32
iInt64
to dużo bardziej przejrzyste w kodzie niż przy użyciu raczej nondescriptiveshort
,int
ilong
Najlepsza odpowiedź, jaką kiedykolwiek słyszałem o używaniu podanych typów aliasów w C #, pochodzi od Jeffreya Richtera w jego książce CLR Via C # . Oto jego 3 powody:
Więc masz to. Myślę, że to są naprawdę dobre punkty. Nie używam jednak rad Jeffreya we własnym kodzie. Być może jestem zbyt utknięty w moim świecie C #, ale w końcu staram się, aby mój kod wyglądał jak kod frameworka.
źródło
string
,int
itplong
jest zdefiniowana jako 64-bitowa liczba całkowita ze znakiem, niezależnie od platformy lub kompilatora. Tak więc w niektórych przypadkach co najmniej, tak, to nie zależą od języka.string
jest zastrzeżonym słowem, aleString
jest tylko nazwą klasy. Oznacza to, że samstring
nie może być użyty jako nazwa zmiennej.Jeśli z jakiegoś powodu chcesz zmiennej o nazwie string , zobaczysz tylko pierwszą z tych kompilacji:
Jeśli naprawdę potrzebujesz nazwy zmiennej o nazwie string , możesz użyć jej
@
jako prefiksu:Kolejna krytyczna różnica: przepełnienie stosu wyróżnia je inaczej.
źródło
@string
jest naprawdę bezcelowe, ponieważ nazwy mieszkańców są obecne tylko w PDB. Równie dobrze można to nazwać_string
czy coś takiego. Bardziej sensowne są rzeczy, które mają nazwy dostępne poprzez odbicie, w miejscu, gdzie@string
byłoby imię członka"string"
.Jest jeszcze jedna różnica - nie można używać
String
bezusing System;
wcześniej.źródło
using
wymagane przeze mnie instrukcje i jawnie usuwam wszystko, czego nie potrzebuję. Power Productivity Tools> „[x] Usuń i sformatuj zastosowania przy zapisywaniu”internal sealed
.Zostało to omówione powyżej; nie możesz jednak używać
string
w refleksji; musisz użyćString
.źródło
typeof(string)
w refleksji. Przykład pierwszy:if (someMethodInfo.ReturnType == typeof(string)) { ... }
Przykład drugi:var p = typeof(string).GetProperty("FirstChar", BindingFlags.NonPublic | BindingFlags.Instance);
Gdzie musisz go użyćString
, a niestring
? Jeśli spróbujesz czegoś takiego jakType.GetType("String")
lubType.GetType("string")
, żadna nie znajdzie klasy, ponieważ brakuje przestrzeni nazw. Jeśli z jakiegoś głupiego powodu porównujesz.Name
typ z"string"
rozróżnianiem wielkości liter, masz rację.System.String
jest klasą ciągów .NET - w C #string
jest aliasemSystem.String
- więc w użyciu są takie same.Jeśli chodzi o wytyczne, nie ugrzęznę zbytnio i po prostu używam tego, na co masz ochotę - w życiu są ważniejsze rzeczy, a kod i tak będzie taki sam.
Jeśli znajdziecie się systemy, w których konieczne jest budynek określić wielkość liczb całkowitych, którego używasz, a więc mają tendencję do używania
Int16
,Int32
,UInt16
,UInt32
itd. To może wyglądać bardziej naturalnie używaćString
- i podczas poruszania się między różnymi językami .net to może uczynić rzeczy bardziej zrozumiałymi - w przeciwnym razie użyłbym łańcucha i int.źródło
short
,int
,ushort
,uint
zamiastInt16
, itd. Głównie dlatego, że jest to jak dowiedziałem. To prawda, żeInt16
łatwiej jest od razu zrozumieć dla osób z mniejszym doświadczeniem. +1 ode mnie!Wolę
.NET
typy pisane wielkimi literami (zamiast aliasów) ze względu na formatowanie. Te.NET
typy są barwione takie same jak innych typów obiektów (typy wartości są odpowiednie obiekty, mimo wszystko).Słowa kluczowe warunkowe i kontrolne (jak
if
,switch
ireturn
) są pisane małymi literami i mają kolor ciemnoniebieski (domyślnie). I wolałbym nie mieć niezgodności w użyciu i formacie.Rozważać:
źródło
Int32 i=1;
zamiast tegoint i = 1;
uważam, że ten pierwszy jest bardziej czytelny pod względem moich zamiarów: mianowicie, że chcę 32-bitową liczbę całkowitą ze znakiem.var
string
iString
są identyczne pod każdym względem (oprócz wielkich liter „S”). Tak czy inaczej, nie ma to wpływu na wydajność.Małe litery
string
są preferowane w większości projektów ze względu na wyróżnianie składniźródło
C # to język używany razem z CLR.
string
jest typem w C #.System.String
jest typem w CLR.Gdy użyjesz C # wraz z CLR
string
zostanie zamapowany naSystem.String
.Teoretycznie można zaimplementować kompilator C #, który wygenerował kod bajtowy Java. Rozsądnym Realizacja tego kompilatora najprawdopodobniej na mapie
string
, abyjava.lang.String
w celu współdziałania z biblioteki uruchomieniowym Java.źródło
string
nie jest typem w C #; jest to słowo zastrzeżone, które odwzorowuje na typ w CLR.Ten film na YouTube pokazuje praktycznie, jak się różnią.
Ale teraz długa odpowiedź tekstowa.
Kiedy mówimy o
.NET
istnieją dwie różne rzeczy jeden jest.NET
ramowy i drugi są języki (C#
,VB.NET
etc), które wykorzystują te ramy.„
System.String
„ aka ”„ String ”(wielkie„ S ”) jest.NET
ramowym typem danych, a„ string ”toC#
typ danych.W skrócie „String” to alias (to samo, co nazywa się różnymi nazwami) „string”. Tak więc technicznie obie poniższe instrukcje kodu dają to samo wyjście.
lub
W ten sam sposób istnieją aliasy dla innych typów danych c #, jak pokazano poniżej: -
Obiekt
System.Object
, string:System.String
, bool:System.Boolean
bajt:System.Byte
, sbyte:System.SByte
krótka:System.Int16
i tak dalejTeraz pytanie za milion dolarów z punktu widzenia programisty Więc kiedy używać „String” i „string”?
Pierwszą rzeczą, aby uniknąć zamieszania, używaj jednego z nich konsekwentnie. Ale z punktu widzenia najlepszych praktyk, kiedy robisz deklarację zmiennej, dobrze jest używać „łańcucha” (małych „s”), a gdy używasz go jako nazwy klasy, preferowany jest „Łańcuch” (wielkie „S”).
W poniższym kodzie lewa strona jest deklaracją zmiennej i zadeklarowana za pomocą „łańcucha”. Po prawej stronie wywołujemy metodę, aby „String” był bardziej sensowny.
źródło
String
, zasugeruj, aby „uprościć kod”, przenosząc go dostring
...Małe litery
string
to pseudonimSystem.String
. Są takie same wC#
.Jest to debata nad tym, czy należy użyć typów systemów (
System.Int32
,System.String
etc.) rodzaje lubC# aliases
(int
,string
itp). Osobiście uważam, że powinieneś skorzystaćC# aliases
, ale to tylko moje osobiste preferencje.źródło
string
jest tylko pseudonimem dlaSystem.String
. Kompilator potraktuje je identycznie.Jedyną praktyczną różnicą jest podświetlanie składni, o czym wspominasz, i że musisz pisać,
using System
jeśli używaszString
.źródło
using System
Podczas używania musisz podać aString
, w przeciwnym razie pojawi się następujący błąd:The type or namespace name 'String' could not be found (are you missing a using directive or an assembly reference?)
Oba są takie same. Ale z perspektywy wytycznych kodowania lepiej jest używać
string
zamiastString
. Tego właśnie używają programiści. np. zamiast używaćInt32
używamyint
jakoint
alias doInt32
Do Twojej wiadomości „Ciąg słów kluczowych jest po prostu aliasem dla predefiniowanej klasy
System.String
”. - Specyfikacja języka C # 4.2.3 http://msdn2.microsoft.com/En-US/library/aa691153.aspxźródło
Jak mówią inni, są tacy sami. Zasady StyleCop domyślnie wymusi na użycie
string
jako kodu C # stylu najlepszych praktyk, z wyjątkiem gdy przedstawieniuSystem.String
funkcje statyczne, takie jakString.Format
,String.Join
,String.Concat
itp ...źródło
Nowa odpowiedź po 6 latach i 5 miesiącach (zwlekanie).
Chociaż
string
jest zarezerwowanym słowem kluczowym C #, które zawsze ma stałe znaczenie,String
jest zwykłym identyfikatorem, który może odnosić się do czegokolwiek. W zależności od elementów bieżącego typu bieżąca przestrzeń nazw oraz zastosowaneusing
dyrektywy i ich umiejscowienieString
mogą być wartością lub typem innym niżglobal::System.String
.Podam dwa przykłady, w których
using
dyrektywy nie pomogą .Po pierwsze, kiedy
String
jest wartością bieżącego typu (lub zmiennej lokalnej):Powyższe nie zostanie skompilowane, ponieważ
IEnumerable<>
nie ma wywołanego elementu niestatycznegoFormat
i nie stosuje się żadnych metod rozszerzenia. W powyższym przypadku nadal może być możliwe użycieString
w innych kontekstach, w których typ jest jedyną możliwością składniową. Na przykładString local = "Hi mum!";
może być OK (w zależności od przestrzeni nazw iusing
dyrektyw).Gorzej: powiedzenie
String.Concat(someSequence)
prawdopodobnie (w zależności odusing
s) przejdzie na metodę rozszerzenia LinqEnumerable.Concat
. Nie przejdzie do metody statycznejstring.Concat
.Po drugie, kiedy
String
jest inny typ , zagnieżdżony w bieżącym typie:Żadna instrukcja w
Example
metodzie się nie kompiluje. TutajString
zawsze jest piano ciąg ,MyPiano.String
. Nie istnieje na nim żaden element członkowski (static
ani nieFormat
jest on dziedziczony z jego klasy podstawowej). A wartości"Goodbye"
nie można na nią przeliczyć.źródło
using String = System.Int32; using Int32 = System.String;
a następnie policzyć błędy.string
jestSystem.String
.String
może być cokolwiek.String
typ, który nie byłby ustawiony na obiekt System.String. Sprawdź: blog.paranoidcoding.com/2019/04/08/…string
ma konkretne znaczenie w języku C #. Jest to typ,System.String
który istnieje w podstawowym zestawie wykonawczym. Środowisko wykonawcze w pełni rozumie ten typ i zapewnia możliwości, których twórcy oczekująstrings
w .NET. Jego obecność jest tak ważna dla C #, że jeśli ten typ nie 't istnieje, kompilator zakończy działanie przed próbą nawet parsowania wiersza kodu. Stądstring
ma precyzyjne, jednoznaczne znaczenie w kodzie C #. IdentyfikatorString
nie ma jednak żadnego konkretnego znaczenia w C #. Jest to identyfikator, który przechodzi przez wszystkie reguły wyszukiwania nazw jakoWidget
,Student
itd ...”Korzystanie z typów System ułatwia przenoszenie między C # i VB.Net, jeśli lubisz takie rzeczy.
źródło
W przeciwieństwie do tego, co wydaje się być powszechną praktyką wśród innych programistów, wolę bardziej
String
niżstring
tylko po to, aby podkreślić fakt, żeString
jest to typ odniesienia, jak wspomniał Jon Skeet.źródło
string
to alias (lub skrót) zSystem.String
. To znaczy, pisząc nastring
myśli, mieliśmy na myśliSystem.String
. Możesz przeczytać więcej na stronie think link: „string” to alias / stenografia System.String.źródło
Chciałbym tylko dodać to do odpowiedzi lfousts z książki Ritchers:
Nie otrzymałem jego opinii, zanim przeczytałem cały akapit.
źródło
String (
System.String
) to klasa w bibliotece klas podstawowych. string (małe litery) to zarezerwowana praca w C #, która jest aliasem dla System.String. Int32 vs int jest podobną sytuacjąBoolean vs. bool
. Te słowa kluczowe specyficzne dla języka C # umożliwiają deklarowanie prymitywów w stylu podobnym do C.źródło
String
nie jest słowem kluczowym i może być używany jako identyfikator, natomiaststring
jest słowem kluczowym i nie może być używany jako identyfikator. I z punktu widzenia funkcji oba są takie same.źródło
To naprawdę kwestia konwencji.
string
wygląda bardziej jak styl C / C ++. Ogólna konwencja polega na korzystaniu ze skrótów udostępnionych przez wybrany język (int / Int dlaInt32
). Dotyczy to również „obiektu”decimal
.Teoretycznie może to pomóc w przeniesieniu kodu do jakiegoś przyszłego standardu 64-bitowego, w którym może oznaczać „int”
Int64
, ale nie o to chodzi, i spodziewałbym się, że każdy kreator aktualizacji zmieni wszelkieint
odniesienia do,Int32
po prostu, aby był bezpieczny.źródło
Spóźniam się na imprezę: używam typów CLR w 100% przypadków (cóż, z wyjątkiem sytuacji, gdy zmuszony jestem używać typu C #, ale nie pamiętam, kiedy to był ostatni raz).
Pierwotnie zacząłem robić to lata temu, zgodnie z książkami CLR autorstwa Ritchie. Miałem dla mnie sens, że wszystkie języki CLR ostatecznie muszą być w stanie obsługiwać zestaw typów CLR, więc użycie tych typów CLR zapewniło jaśniejszy i prawdopodobnie bardziej „wielokrotnego użytku” kod.
Teraz, gdy robię to od lat, jest to nawyk i podoba mi się ubarwienie, które VS pokazuje dla typów CLR.
Jedynym minusem jest to, że autouzupełnianie używa typu C #, więc kończę przepisywanie automatycznie generowanych typów w celu określenia typu CLR.
Również teraz, gdy widzę „int” lub „string”, wygląda mi to naprawdę źle, tak jak patrzę na kod C z 1970 roku.
źródło
Nie ma różnicy.
Słowo kluczowe C #
string
odwzorowuje na typ .NETSystem.String
- jest to alias, który utrzymuje konwencje nazewnictwa języka.Podobnie
int
mapy doSystem.Int32
.źródło
int*
i typy złożone z [U] IntPtr lub rzeczywistych wskaźników).Cytat na ten temat z książki Daniela Solisa .
źródło
ciąg jest słowem kluczowym i nie można użyć łańcucha jako identyfikatora.
Łańcuch nie jest słowem kluczowym i można go użyć jako identyfikatora:
Przykład
Słowo kluczowe
string
jest pseudonimemSystem.String
oprócz problemu ze słowem kluczowym, oba są dokładnie równoważne.źródło
Tak, to nie jest różnica między nimi, podobnie jak
bool
iBoolean
.źródło
@JaredPar (twórca kompilatora C # i płodny użytkownik SO!) Napisał świetny post na blogu na ten temat. Myślę, że warto się tutaj podzielić. To miłe spojrzenie na nasz temat.
Uwaga: skopiowałem / wkleiłem większość postów na blogu z przyczyn archiwalnych. Ignoruję niektóre części, więc jeśli to możliwe , polecam pominąć i przeczytać post na blogu .
źródło