Dize ve C # dize arasındaki fark nedir?


6507

Örnek (durumu not edin ):

string s = "Hello world!";
String s = "Hello world!";

Her birinin kullanımına ilişkin yönergeler nelerdir? Farklılıklar nelerdir?


72
@ORMapper ama aslında kalıntıları stringa, sözcük C arasında yapı gramer ise System.Stringbir türüdür. Herhangi bir spesifikasyonda belirtilen herhangi bir açık farktan bağımsız olarak , yine de bazı belirsizlikler ile karşılanabilecek bu örtülü fark vardır. Dilin kendisi , uygulamanın BCL'de belirli bir sınıf için dikkate almak zorunda kalmayacağı bir şekilde desteklemesi gerekirstring .
Kirk Woll

106
Dil özelliklerine göre, dil kendisi: @KirkWoll gerekir düşünün stringBCL türü olarak tamamen aynı olması System.String, başka bir şey. Bu hiç de belirsiz değil. Tabii ki, C # dilbilgisini kullanarak kendi derleyicinizi uygulayabilir ve böyle bulunan tüm belirteçleri, C # dil belirtiminde tanımlananla alakasız, rastgele bir şey için kullanabilirsiniz. Ancak, ortaya çıkan dil sadece bir C # benzeri olacaktır, C # olarak kabul edilemez.
VEYA Haritacı

88
stringSistem için bir yönerge kullanmadan kullanabilirsiniz . Bunu ile yapamazsın String.
Wilsu

14
Algol ve Fortran'dan gelen biri için bu tartışmada bir sorun var string. Kısaltmak gerekiyor System.String, ancak, bir takma ad olarak, oldukça benziyor, ancak tam olarak aynı şey değil. Yine de, birkaç yıl C # sonra, sadece kullanmak stringve string.Format()endişelenmemek güvenli olduğunu söyleyebilirim System.String.
Roland

8
@Sangeeta Ne diyorsun sen? System.StringSınıf hala orada ve stringanahtar kelime hala bunun için bir diğer adıdır. Tıpkı System.Int32ve gibi int. Kelimenin tam anlamıyla aynı şey.
Craig

Yanıtlar:


6104

string, C # için bir takma addır System.String.
Yani teknik olarak hiçbir fark yok. Sanki int vs. System.Int32 .

Kurallara göre, genellikle stringbir nesneye atıfta bulunduğunuz her an kullanılması önerilir .

Örneğin

string place = "world";

Aynı şekilde, Stringözellikle sınıfa başvurmanız gerekiyorsa, genellikle kullanılması tavsiye edilir .

Örneğin

string greet = String.Format("Hello {0}!", place);

Bu, Microsoft'un örneklerinde kullanma eğilimindedir .

StyleCop artık C #'a özgü takma adların kullanımını zorunlu kıldığından , bu alandaki rehberliğin değişmiş olabileceği anlaşılmaktadır .


163
StyleCop kullanmaya karar verirseniz ve bunu takip ederseniz, bu dile özgü türleri kullanmak anlamına gelir. Yani C # için string (String yerine), int (Int32 yerine), float (Single yerine) var - stylecop.soyuz5.com/SA1121.html
Dominic Zukiewicz

144
Her zaman takma adları kullanıyorum çünkü bir gün kullanışlı olabileceğini düşündüm, çünkü bir soyutlama görevi görüyorlar, bu yüzden uygulamalarını bilmeme gerek kalmadan değiştirebilirler.
Rob

37
Visual Studio 2015, String.Format'ın string.Format olarak değiştirilmesi gerektiğini söylüyor, bu yüzden sanırım Microsoft bu şekilde gidiyor. Ayrıca her zaman statik yöntemler için String kullandık.
Sami Kuhmonen

32
Bunları okuduğumdan, yorumların birçoğunun sadece yanlış olduğunu fark ettim. @ DRAirey1 Zamanla, eski yolun hala en iyisi olduğunu göreceksiniz, o zaman Visual Studio kullanmadan C # kodu yazmaya çalışmanıza cesaret ederseniz. Bu neredeyse imkansız ve web geliştirme çalışmalarında zaman zaman ortaya çıkan bir durum. @Vlad: String'i kullanmak için herhangi bir şey içe aktarmanıza gerek yoktur. @Abhi Yorumunuz anlamsız ve aynı derecede doğrudur string.Format(). @KlitosG Hayır, bu doğru değil. Hepsi aynı şekilde çalışır.
krowe2

46
Aslında bir fark olduğunu söyleyebilir misiniz? Örneğin: nameof(string)derlenmeyecek nameof(String).
Jeroen Vannevel

3439

Sadece bütünlük adına, işte ilgili bilgilerin bir beyin dökümü ...

Diğerlerinin belirttiği gibi, stringiçin bir takma addır System.String. Aynı kodu derlerler, bu yüzden yürütme zamanında herhangi bir fark yoktur. Bu C # 'daki takma adlardan sadece biridir. Tam liste:

object:  System.Object
string:  System.String
bool:    System.Boolean
byte:    System.Byte
sbyte:   System.SByte
short:   System.Int16
ushort:  System.UInt16
int:     System.Int32
uint:    System.UInt32
long:    System.Int64
ulong:   System.UInt64
float:   System.Single
double:  System.Double
decimal: System.Decimal
char:    System.Char

Bunun dışında stringve object, takma adlar değer türleri için tüm vardır. decimalbir değer türüdür, ancak CLR'de ilkel bir tür değildir. Takma adı olmayan tek ilkel tür System.IntPtr.

Spesifikasyonda, değer türü takma adları "basit türler" olarak bilinir. Değişmez değerler her basit türün sabit değerleri için kullanılabilir; başka hiçbir değer türünün gerçek formu yoktur. (Bunu, DateTimedeğişmez değerlere izin veren ve bunun için bir takma adı olan VB ile karşılaştırın .)

Takma adları kullanmanız gereken bir durum vardır : bir enum'un altında yatan türü açıkça belirtirken . Örneğin:

public enum Foo : UInt32 {} // Invalid
public enum Bar : uint   {} // Valid

Bu şekilde meselesi Spec tanımlar enum bildirimleri var - kolon sonra parçası olmak zorunda ayrılmaz tipi bir belirteç olan üretim, sbyte, byte, short, ushort, int, uint, long, ulong, char... bir karşıt olarak tip üretim olarak örneğin değişken bildirimleri tarafından kullanılır. Başka bir fark belirtmez.

Son olarak, hangi kullanım söz konusu olduğunda: kişisel olarak uygulama için her yerde takma adları kullanıyorum, ancak herhangi bir API için CLR türü. Uygulama açısından hangisini kullandığınız gerçekten çok önemli değil - ekibiniz arasındaki tutarlılık iyi, ancak kimse ilgilenmeyecek. Öte yandan, bir API'daki bir türe başvurursanız, bunu dilden bağımsız bir şekilde yapmanız gerçekten önemlidir. Denilen bir yöntem ReadInt32açıktır, oysa denilen bir yöntem ReadIntyorum gerektirir. Arayan , örneğin bir inttakma ad tanımlayan bir dil kullanıyor olabilir Int16. .NET framework tasarımcıları, bu deseni izlemiştir iyi örnekler olmak BitConverter, BinaryReaderve Convertsınıflar.


82
Enum ile kalıtım durumu ilginç. Numaralandırma için takma adın neden kullanılması gerektiğine dair belgelere işaret edebilir misiniz? Yoksa bu bilinen bir hata mı?
JaredPar

149
Spec 14.1 bölümünde (çok uzun olduğu için burada kolayca alıntı olamaz). Diğer adı kullanmanız gerektiğini açıkça söylemez, ancak diğer adlar bir tür kendi türü olarak ele alınır. Her şey biraz garip.
Jon Skeet

32
@PiPeep, büyük miktarda upvotes'tan daha şaşırtıcı olan, şaşırtıcı derecede düşük downvotes'dur (ilk 5 gönderinin toplam 2000'den fazla upvole sahip olduğunu ve bunların arasında sadece 1 downvote olduğunu düşünün). Özellikle herhangi bir toplumda her zaman "nefret edenlerin" olduğu fikrini hesaba kattığınızda bunu gerçekten inanılmaz buluyorum.
corsiKa

40
Arasında ilginç bir fark stringve Stringolmasıdır string' is a keyword in c#, so you can not use it as a variable name.For Ex: "Merhaba" = dize dize; //compiler error, but String String = "hi"; `kabul edilebilir, çünkü Stringbir anahtar kelime değil.
Sanjeev Rai

33
@SanjeevRai: Evet. Sonunda gibi @stringgörünen bir tanımlayıcı oluşturmak için kullanabilirsiniz string. Bu bir tür kaçış mekanizması.
Jon Skeet

716

Stringkısaltmasıdır System.Stringve bir .NET Framework türüdür. için C # dilinde stringbir takma addırSystem.String . Her ikisi de System.StringIL'de (Orta Dil) derlenmiştir , bu yüzden fark yoktur. Ne sevdiğini seç ve kullan. C # kodlarsanız, ben stringC # türü takma adı ve C # programcılar tarafından bilinen tercih ederim .

( int, System.Int32) Vb. İçin de aynı şeyi söyleyebilirim .


3
`C # 'da kod yazarsanız, C # türü takma adı olduğu ve C # programcıları tarafından iyi bilindiği için dizeyi tercih ederim - bir C # kişi .NET çerçevesini ne zaman bilemez. Bence +1 genellikle bu en iyi cevap, ama bahsettiğim nokta garip görünüyor.
MyDaftQuestions

4
Ben şahsen "Int32" kullanmayı tercih ediyorum, çünkü hemen değer aralığını gösteriyor. Sonraki yüksek bit sistemlerde "int" türünü yükseltip yükseltmediklerini düşünün. c'deki 'int' görünüşte "hedef işlemcinin en verimli çalıştığı tamsayı türü" olarak görülür ve "en az 16 bit" olarak tanımlanır. Orada öngörülebilir tutarlılığı tercih ederim, çok teşekkür ederim.
Nyerguds

2
@MyDaftQuestions Katılıyorum. Herhangi bir şey olursa , .net türlerini tutarlı bir şekilde kullanmak mantıklıdır ve türler açıktır, herhangi bir dilden bağımsızdır (F # 'ın veya VB'nin tüm deyimlerini biliyor muyum?).
Peter - Monica'yı

5
@Nyerguds Sadece endişelenmemek için iki sebep var. Birincisi, intC # dil spesifikasyonunda donanıma bakılmaksızın 32 bit tam sayı olarak tanımlanmış olmasıdır. C #, zaman sislerinde paylaşılan bir mirasa rağmen, aslında C değildir. int64 bitlik bir tam sayıya geçmek, spesifikasyonda ve dilde bir kırılma değişikliği olacaktır. Şu anda 64 bit tam sayı olduğu longgibi yeniden tanımlamayı da gerektirir long. Endişelenmemenin diğer nedeni, türler asla değişmeyeceğinden önemsizdir, ancak .NET,% 99'unun zaten düşünmek zorunda kalmayacağınız kadar soyuttur. ;-)
Craig

5
Ben nerede eski tescilli oyun biçimlerinin çok içine kazmak @Craig yok o tüm zamanların düşünmek zorundayız olsa. Sonra kullanarak Int16, Int32ve Int64bir olduğunu çok ziyade nondescriptive kullanmaktan daha kodunda daha şeffaf short, intvelong
Nyerguds

505

C # 'da sağlanan tür takma adlarını kullanma hakkında duyduğum en iyi cevap, CLR Via C # adlı kitapta Jeffrey Richter'den geliyor . İşte 3 nedeni:

  • Kodlarında dize mi yoksa Dize mi kullanılacağını bilmeden, bir dizi geliştiricinin kafası karıştığını gördüm . C # 'da dize (bir anahtar kelime) tam olarak System.String (FCL türü) ile eşleştiğinden, hiçbir fark yoktur ve her ikisi de kullanılabilir.
  • C # 'da uzun System.Int64 ile eşlenir , ancak farklı bir programlama dilinde uzun bir Int16 veya Int32 ile eşlenebilir . Aslında, C ++ / CLI aslında bir Int32 kadar tedavi eder . Bir dilde kaynak kodu okuyan biri, farklı bir programlama dilinde programlamaya alışkınsa, kodun niyetini kolayca yanlış yorumlayabilir. Aslında, çoğu dil uzun süre bir anahtar kelime gibi davranmaz ve onu kullanan kodu derlemez.
  • FCL, yöntem adlarının bir parçası olarak tür adlarına sahip birçok yönteme sahiptir. Örneğin, BinaryReader türü ReadBoolean , ReadInt32 , ReadSingle ve benzeri yöntemler sunar ve System.Convert türü ToBoolean , ToInt32 , ToSingle ve benzeri yöntemler sunar . Aşağıdaki kodu yazmak yasal olsa da, şamandıralı çizgi bana çok doğal gelmiyor ve çizginin doğru olduğu belli değil:
BinaryReader br = new BinaryReader(...);
float val  = br.ReadSingle(); // OK, but feels unnatural
Single val = br.ReadSingle(); // OK and feels good

İşte burada. Bunların hepsi gerçekten iyi noktalar. Ancak, kendi kodumda Jeffrey'nin tavsiyesini kullanarak kendimi bulamıyorum. Belki de C # dünyamda takılıp kaldım ama kodumu çerçeve koduna benzetmeye çalışıyorum.


24
İkinci nokta bir sebep gibi aslında sesler değil kullanımına string, intvb
MauganRa

15
@MauganRa Ve kitabın yazarı, takma adları kullanmadığı için bu nedenleri listeliyor .
tomi.lee.jones

31
"Birisi C # kaynak kodunu okuyorsa, başka bir dile özgü değil, dil özelliğine göre yorumlaması gerekir." Bu tamamen noktayı kaçırıyor. Herkesin bu değil niyetinde bir tür programcı başka bir bağlamda günlük olarak gördüğü farklı bir anlama sahip olduğunda, kişinin beyin yanlış sonuca atlamak için basitçe kolay, kod yanlış anlaşılabilir. Hepimiz hata yaparız; açıkça adlandırılmış türler kullanmak bu hataları daha az olası kılar.
Darryl

10
+ Bu nedenler konu hakkındaki hislerimi özetliyor. C # 'da kodlamaya başladığımda (Java / C ++ / C arka planından geliyor) takma adların çirkin olduğunu düşündüm. Hala böyle hissediyorum, maalesef dünyanın çoğu benimle aynı fikirde değil ya da umursamıyorlar ve küçük harf kullanıyorlar.
gusgorman

8
@jinzai soru longplatform veya derleyici ne olursa olsun, imzalı bir 64 bit tam sayı olarak tanımlanan C # ile ilgili . En azından bazı durumlarda Yani, evet, bu mu diline bağlıdır.
phoog

455

stringayrılmış bir sözcüktür, ancak Stringyalnızca bir sınıf adıdır. Bu string, tek başına değişken adı olarak kullanılamayacağı anlamına gelir .

Herhangi bir nedenle string adlı bir değişken isteseydiniz , bu derlemelerin yalnızca ilkini görürsünüz:

StringBuilder String = new StringBuilder();  // compiles
StringBuilder string = new StringBuilder();  // doesn't compile 

Gerçekten string adında bir değişken adı istiyorsanız @önek olarak kullanabilirsiniz :

StringBuilder @string = new StringBuilder();

Başka bir kritik fark: Yığın Taşması bunları farklı şekilde vurgular.


20
Yerel bir @stringadın yalnızca PDB'lerde bulunduğundan, yerel bir aramanın gerçekten anlamsız olduğunu unutmayın . Bunu _stringfalan da söyleyebiliriz . Üyelerin adının nerede @stringolacağı , yansıma yoluyla isimlere erişilebilen şeyler için daha mantıklıdır "string".
Roman Starkov

25
Ayrılmış bir kelimeyi değişken bir isim olarak kullanmak da oldukça yetersizdir.
Elton

7
OP, String veya string'i değişken adı olarak kullanmak istemez. Bu Türler arasındaki farkın açıklanmasını istediler . Cevabınız sadece daha fazla karışıklık eklemek için hizmet veriyor IMO
Matt Wilko

1
@craig eğer insanlara düğüm bağlamayı öğretmek için yazılım yazıyor olsaydınız?
Simon_Weaver

5
Dizelerde @Simon_Weaver düğüm? Haha güzel. :-) Tabii ki, iplik gibi alternatif bir isim seçebilirsiniz. Bir dakika ... Ah!
Craig

391

Tek fark var - sen kullanamazsınız Stringolmadan using System;önceden.


14
varsayılan olarak çoğu kişi bunu dosyanın üst kısmına herhangi bir şekilde ekler. VS bunu çoğu durumda varsayılan olarak yapmaz!
IbrarMumtaz

9
Varsayılan olarak yalnızca istediğim usingifadeleri eklerim ve açıkça istemediğim her şeyi kaldırırım. Enerji Verimliliği Araçları> "[x] Tasarruf Durumundaki Kullanımları Kaldır ve Biçimlendir"
JMD

2
@JMD .cs şablon dosyasını değiştirdim, böylece üstte herhangi bir kullanma ifadesi bile yok! Sınıf şablonunu da değiştirdim internal sealed.
ErikE

@JMD Bu özellikten nefret ediyorum. Bazen başka bir şekilde dokunulmamış dosyalarda değişiklik yapar ve bu da bir değişiklik kümesinin gerçek değişikliklerini görmeyi zorlaştırır. Tabii ki genellikle "spam kullanarak" kaldırıyorum, ama sadece aktif olarak, otomatik olarak değil.
mg30rg

Bu C # için geçerli olabilir, ancak tüm .NET dilleri için geçerli olmayabilir. (Powershell, varsayılan olarak Sistem ad alanını içe aktarır.)
FSCKur

311

Yukarıda ele alınmıştır; ancak stringyansımada kullanamazsınız ; kullanmalısın String.


6
Bu cevabın ne anlama geldiğini ve neden kaldırıldığını anlamıyorum. Yansımayı kullanabilirsiniz typeof(string). Birinci if (someMethodInfo.ReturnType == typeof(string)) { ... }örnek: var p = typeof(string).GetProperty("FirstChar", BindingFlags.NonPublic | BindingFlags.Instance);İkinci örnek: Nerede kullanmalısınız String, değil stringmi? Type.GetType("String")Veya gibi şeyleri denerseniz Type.GetType("string"), ad alanı eksik olduğu için de sınıfı bulamazsınız. Bazıları için ise saçma bir nedenle karşılaştırmak .Nameiçin bir tür "string"küçük harfe duyarlı bir şekilde, haklısınız.
Jeppe Stig Nielsen

256

System.String.NET dize sınıfıdır - C # stringiçin bir takma addır System.String- kullanımda aynıdır.

Kurallara gelince, çok fazla saplanmayacaktım ve sadece hangisini istersen kullanacağım - hayatta daha önemli şeyler var ve kod yine de aynı olacak.

Eğer kullandığınız tamsayılar boyutunu belirlemek için gereklidir sistemleri bina kendinizi bulmak ve böylece kullanım eğilimi varsa Int16, Int32, UInt16, UInt32vb o zaman kullanmak daha doğal görünebilir String- ve farklı .net dilleri arasında hareket ederken might işleri daha anlaşılır kılmak - aksi takdirde string ve int kullanırdım


2
Sadece birini seç ve tutarlı ol. Ev tarzında bir yerde çalışıyorsanız, bunu kullanın.
Alan B

3
maalesef stil kişisel bir tercihtir ve özel kod sahibi olmayan birkaç takım arasında büyük bir kod tabanını uygulamak için çok pahalı olabilir. string vs String yerine dikkat edilmesi gereken her zaman daha önemli konular vardır. Bu da bizi "hayatta daha önemli şeylere" geri getiriyor
aiodintsov

Bu kesinlikle tercih edilen bir şey; örneğin: Ben kullanmayı tercih short, int, ushort, uintyerine Int16bu öğrendiğim nasıl Çoğunlukla çünkü vb. Kabul edilirse, Int16daha az deneyime sahip olanlar için hemen anlaşılması daha kolaydır. +1 Benden!
Candleshark

210

.NETBiçimlendirme amacıyla büyük harfli türleri (takma adlar yerine) tercih ederim . .NETTürleri, diğer nesne türleri (değer türleri sonuçta, doğru nesnelerdir) ile aynı renklidir.

Şartlı ve kontrol anahtar kelimeler (gibi if, switchve return) küçük harf ve renkli koyu mavi (varsayılan olarak). Ve kullanım ve format konusunda anlaşmazlığı tercih etmemeyi tercih ederim.

Düşünmek:

String someString; 
string anotherString; 

11
Ayrıca şöyle bir kod yazıyor musunuz: Int32 i = 1; İnt i = 1 yerine; ? Kullanılabilir olduğunda dize takma adını kullanmamak tutarsız görünüyor.
bytedev

29
@nashwan: aslında, evet, Int32 i=1;öncekinin amacım açısından int i = 1; daha okunabilir olduğunu düşünüyorum: yani 32 bit işaretli bir tamsayı istiyorum.
NotMe

5
Peki tüm bunlar geliştirici C # kodu (dize) veya .NET kodu (Dize) yazıyor düşünüyor bağlıdır sanırım. Şahsen ben C # yazıyorum düşünüyorum (ve .NET kullanan C #).
bytedev

7
@Alex: Amacım, belirsizliği kaldırmak için kodlamamda çok spesifik olmayı tercih etmemdi.
NotMe

22
Spektrumun mutlak diğer ucunda, neredeyse her zaman kullanırımvar
tic

192

stringve Stringher şekilde aynıdır (büyük harf "S" hariç). Her iki durumda da herhangi bir performans etkisi yoktur.

stringSözdizimi vurgulaması nedeniyle çoğu projede küçük harf tercih edilir


Jeffrey Richter, burada meydana gelen karışıklığı önlemek için her durumda CLR türünü (C # üzerinden CLR) kullanmanızı önerir.
Josh

Açıkça, ister S ister s kullanın, bu sorulara neden olacak, bu yüzden Richter'i aşağı oylayın. ;)
Brad Wilson

Richter, dizenin bir seçenek olmaması gerektiği anlamına geliyordu - Microsoft'un dilde olmaması gerekiyordu. Richter'e oy veremezsin - o bir efsane! :)
Joe Ratzer

1
Takma adlara sahip olmamanın daha iyi olabileceğini kabul ediyorum . Ancak onlara sahip olduğumuz göz önüne alındığında, bunları kullanmanın iyi olduğunu düşünüyorum (ancak yöntem adlarında vb. Değil)
Jon Skeet

10
"string", "String" ile aynı değildir. "System.String" anlamına gelir. Yani "String" kullanırsanız, isim alanını eklemek için "System'i kullanarak" koymak zorundasınız
ThiagoAlves

185

C #, CLR ile birlikte kullanılan bir dildir.

string C # 'da bir tür.

System.String CLR'de bir türdür.

C # ile birlikte kullanıldığında CLR stringile eşlenir System.String.

Teorik olarak, Java bayt kodu oluşturan bir C # derleyicisi uygulayabilirsiniz. Bu derleyici bir mantıklı uygulanması muhtemelen eşlersiniz stringiçin java.lang.StringJava çalışma zamanı kitaplığı ile birlikte çalışan amacıyla.


1
stringC # ' da bir tür değildir ; CLR'deki bir türle eşleşen ayrılmış bir kelimedir.
CesarGon

@CesarGon: ECMA-334'e göre, bölüm 8.2.1: "C #, bir dizi önceden tanımlanmış tür sağlar [...] Önceden tanımlanmış referans türleri nesne ve dizgidir."
Rasmus Faber

10
ECMA-334, bölüm 9.4.3'e göre, "dize" bir anahtar kelimedir. :-) Semantiklere odaklanırsanız, "string" in bir tür olduğunu kabul ediyorum, ancak sözdizimine odaklanırsanız bunun bir anahtar kelime (yani ayrılmış bir kelime) olduğunu söyleyebilirim. Standart her iki bakış açısını da destekliyor (belki de çok belirsiz!). Bana göre OP sözdizimi ile ilgili, bu yüzden cevaplara baktığımda sözdizimine odaklanma eğilimindeyim, ama ben de senin fikrini görüyorum. Ayrıca, cevabınız, olduğu gibi, iki farklı türün var olduğu anlamına gelebilir: dize ve Dize, durum böyle olmadığında. Biri diğeriyle eşleşmedir.
CesarGon

Bu konuda net olalım. 'dize' ayrılmış bir takma addır. Gerçek bir veri türü değildir. Başka bir şeye işaret eden bir şeydir. Tüm bu takma adları kaldırabilir (veya hiçbir zaman kullanamazsınız) ve mükemmel bir programlama diline sahip olabilirsiniz.
Quarkly

168

Bu YouTube videosu pratikte nasıl farklı olduklarını gösterir.

Ama şimdi uzun bir metin cevabı için.

Biz bahsederken .NETiki farklı şey var bir tane var .NETçerçeve ve diğer diller (vardır C#, VB.NETo çerçeveyi kullanmak vs).

resim açıklamasını buraya girin

" System.String" aka "String" (büyük "S") bir .NETçerçeve veri türüdür, "string" ise bir C#veri türüdür.

resim açıklamasını buraya girin

Kısacası "String", "string" ifadesinin bir takma adıdır (farklı adlarla aynı addır). Teknik olarak aşağıdaki kod ifadelerinin her ikisi de aynı çıktıyı verecektir.

String s = "I am String";

veya

string s = "I am String";

Aynı şekilde, aşağıda gösterildiği gibi diğer c # veri türü için takma adlar vardır: -

object:, System.Objectstring:, System.Stringbool:, System.Booleanbayt:, System.Bytesbyte:, System.SByteshort: System.Int16vb.

Şimdi programcının bakış açısından milyon dolarlık soru Peki ne zaman "String" ve "string" kullanılır?

Karışıklıktan kaçınmak için ilk şey, bunlardan birini sürekli kullanın. Ancak en iyi uygulamalar perspektifinden, değişken bildirimi yaptığınızda "string" (küçük "s") kullanmak iyidir ve sınıf adı olarak kullandığınızda "String" (capital "S") tercih edilir.

Aşağıdaki kodda sol taraf bir değişken bildirgesidir ve "string" kullanılarak bildirilmiştir. Sağ tarafta "String" daha mantıklı bir yöntem çağırıyoruz.

string s = String.ToUpper() ;

25
"Kısaca" Dize "," dize "" nin takma adıdır (farklı adlarla aynı addır). Bu doğru değil: takma ad "dize" dir.
Xavier Egea

3
Değişken bildirimi yaptığınızda "string" (küçük "s") kullanmak iyidir ve bunu sınıf adı olarak kullandığınızda "String" (capital "S") tercih edilir. Bu kural artık geçerli görünmüyor: Visual Studio 2015 kullanıyorsanız ve yazmaya çalıştığınızda String, "kodunuzu basitleştirin" ve onu taşımaya çalışın string...
Massimiliano Kraus

165

Küçük harf stringbir takma addır System.String. Onlar aynı C#.

Sistem türleri (kullanmak gerekip gerekmediği konusunda bir tartışma var System.Int32, System.Stringvs.) tipleri veya C# aliases( int, string, vs). Kişisel olarak kullanmanız gerektiğine inanıyorum C# aliases, ama bu sadece benim kişisel tercihim.


4
Sorun bu, 'C #' takma adı değil, 'C' takma adı. C # dilinde yerel bir 'dize' veya 'int' yoktur, sadece sözdizimsel şekerdir.
Quarkly

16
"C" nin nereden geldiğinden emin değilim, C # 5 dil belirtimi "Anahtar kelime dizesi, önceden tanımlanmış System.String sınıfı için bir takma addır." sayfa 85, paragraf 4.2.4. Tüm üst düzey diller CPU komut setleri ve bayt kodu üzerinden sözdizimsel şekerdir.
aiodintsov

156

stringsadece bir takma addır System.String. Derleyici onlara aynı şekilde davranacaktır.

Sadece pratik fark söz olarak vurgulama sözdizimi ve yazma gerektiğini using Systemkullanırsanız String.


Dize kullanmak için Sistem önekini kullanmanıza gerek yoktur.
Joe Ratzer

18
using SystemKullanırken bir dahil Stringetmeniz gerekir, aksi takdirde aşağıdaki hatayı alırsınız:The type or namespace name 'String' could not be found (are you missing a using directive or an assembly reference?)
Ronald

143

İkisi de aynı. Ancak kodlama yönergeleri bakış açısından, bunun stringyerine kullanmak daha iyidir String. Genellikle geliştiriciler bunu kullanır. ör. takma ad olarak Int32kullanmak yerineintintInt32

FYI “Anahtar kelime dizesi, sadece önceden tanımlanmış sınıf için bir takma addır System.String.” - C # Dil Özellikleri 4.2.3 http://msdn2.microsoft.com/En-US/library/aa691153.aspx


120

Diğerlerinin söylediği gibi, onlar aynı. StyleCop kuralları, varsayılan olarak, kullanmak zorunlu kılar stringC # kodu stili olarak başvuran dışında en iyi uygulamaları, System.Stringgibi statik işlevleri String.Format, String.Join, String.Concat, vb ...


4
Statik yöntemler dışında - StyleCop Dize kullanımını işaretleyeceğini bilmiyordum. Statik üyelere eriştiğinizde, tip bildirimleri ve Dize için dize nasıl kullanacağım gibi harika olduğunu düşünüyorum.
Goyuix

101

6 yıl 5 ay sonra yeni cevap (erteleme).

Her stringzaman sabit bir anlamı olan ayrılmış bir C # anahtar kelime olsa da , herhangi bir şeye atıfta bulunabilecek Stringsıradan bir tanımlayıcıdır . Geçerli türün üyelerine bağlı olarak, geçerli ad alanı ve uygulanan usingyönergeler ve bunların yerleşimi, Stringfarklı bir değer veya tür olabilir global::System.String.

usingDirektiflerin yardımcı olmayacağı iki örnek vereceğim .


İlk olarak, bir Stringa, değer akım tipi (veya yerel bir değişken) ait:

class MySequence<TElement>
{
  public IEnumerable<TElement> String { get; set; }

  void Example()
  {
    var test = String.Format("Hello {0}.", DateTime.Today.DayOfWeek);
  }
}

Yukarıdaki derlenmeyecektir, çünkü IEnumerable<>çağrılan statik olmayan bir üyesi Formatyoktur ve hiçbir uzantı yöntemi uygulanmaz. Yukarıdaki durumda, Stringbir tipin sözdizimsel olarak tek olasılık olduğu başka bağlamlarda da kullanılabilir . Örneğin String local = "Hi mum!";, Tamam olabilir (ad alanına ve usingdirektiflere bağlı olarak ).

Daha kötüsü: Söylemek String.Concat(someSequence)büyük olasılıkla ( usings'ye bağlı olarak ) Linq uzatma yöntemine gidecektir Enumerable.Concat. Statik yönteme gitmeyecektir string.Concat.


İkinci olarak, geçerli türün içine yerleştirilmiş Stringbaşka bir tür ne zaman :

class MyPiano
{
  protected class String
  {
  }

  void Example()
  {
    var test1 = String.Format("Hello {0}.", DateTime.Today.DayOfWeek);
    String test2 = "Goodbye";
  }
}

ExampleYöntemdeki ifadelerin hiçbiri derlenmez. İşte Stringbir piyano daima dize , MyPiano.String. Üzerinde üye yok ( staticveya yok) Format(veya temel sınıfından miras alınmış). Ve değer "Goodbye"buna dönüştürülemez.


4
Şeytani biri olabilir: using String = System.Int32; using Int32 = System.String; ve sonra hataları saymak.
Steve

7
Bu doğru cevap. stringolduğunu System.String. Stringherhangi bir şey olabilir.
Dave Cousineau

@DaveCousineau kabul etti - bu takma adın noktası. StringSystem.String nesnesine ayarlanmayacak başka bir tür oluşturabilirsiniz . Çıkış: blog.paranoidcoding.com/2019/04/08/…
Kristopher

"Anahtar kelimenin stringC # 'da somut bir anlamı vardır. System.StringÇekirdek çalışma zamanı derlemesinde bulunan türdür . Çalışma zamanı özünde bu türü anlar ve geliştiricilerin strings.NET'te beklediği yetenekleri sağlar . Varlığı C # için çok kritiktir. Derleyici bir kod satırını ayrıştırmaya çalışmadan önce çıkmayacaktır.Bu nedenle stringC # kodunda kesin, açık bir anlamı vardır.Kimici C # ' Stringda somut bir anlamı olmamakla birlikte, tüm isim arama kurallarından geçen bir tanımlayıcıdır. as Widget,, Studentetc… "
Kristopher



87

Başka hangi programcılar arasında yaygın bir uygulama gibi görünüyor karşı, tercihim Stringüzerinde stringsadece gerçeği vurgulamak için StringJon Skeet belirtildiği gibi, bir referans türüdür.



78

Bunu sadece Ritchers kitabından lfousts cevabına eklemek istiyorum:

C # dil belirtimi, “Bir stil meselesi olarak, tam sistem türü adının kullanılması yerine anahtar kelimenin kullanılması tercih edilir.” Dil şartnamesine katılmıyorum; FCL tür adlarını kullanmayı ve ilkel tür adlarından tamamen kaçınmayı tercih ederim. Aslında, derleyicilerin ilkel tip isimleri ve geliştiricileri FCL tip isimlerini kullanmaya zorlamadım. İşte nedenlerim:

  • Kodlarında dize mi yoksa Dize mi kullanılacağını bilmeden, bir dizi geliştiricinin kafası karıştığını gördüm . C # dizgisinde (bir anahtar kelime) System.String (FCL türü) ile tam olarak eşleştiği için fark yoktur ve her ikisi de kullanılabilir. Benzer şekilde, bazı geliştiriciler söylediğini duymuştum int uygulaması 32-bit işletim sistemi çalıştıran bir 32 bit tam sayı ve uygulamanın 64-bit işletim sistemi üzerinde çalışan 64 bitlik tamsayı temsil ettiğini. Bu ifade kesinlikle yanlıştır: C # 'da, int her zaman System.Int32 ile eşleşir ve bu nedenle kodun çalıştığı işletim sistemine bakılmaksızın 32 bitlik bir tamsayıyı temsil eder. Programcılar kullanırsaInt32 kodlarında, bu potansiyel karışıklık da ortadan kaldırılır.

  • C # 'da uzun System.Int64 ile eşlenir , ancak farklı bir programlama dilinde uzun bir Int16 veya Int32 ile eşlenebilir . Aslında, C ++ / CLI bir Int32 kadar uzun davranır . Bir dilde kaynak kodu okuyan biri, farklı bir programlama dilinde programlamaya alışkınsa, kodun niyetini kolayca yanlış yorumlayabilir. Aslında, çoğu dil uzun süre bir anahtar kelime gibi davranmaz ve onu kullanan kodu derlemez.

  • FCL, yöntem adlarının bir parçası olarak tür adlarına sahip birçok yönteme sahiptir. Örneğin, BinaryReader türü ReadBoolean , ReadInt32 , ReadSingle vb. Yöntemler sunar ve System.Convert türü ToBoolean , ToInt32 , ToSingle vb. Yöntemler sunar . Aşağıdaki kodu yazmak yasal olsa da, şamandıralı çizgi bana çok doğal gelmiyor ve çizginin doğru olduğu belli değil:

    BinaryReader br = new BinaryReader(...);
    float val = br.ReadSingle(); // OK, but feels unnatural
    Single val = br.ReadSingle(); // OK and feels good
  • C # kullanan birçok programcı, CLR'ye karşı diğer programlama dillerinin kullanılabileceğini unutmaya eğilimlidir ve bu nedenle C # mekanizmaları sınıf kitaplığı koduna girer. Örneğin, Microsoft'un FCL neredeyse sadece C # ile yazılmış ve FCL takımında geliştiriciler artık kütüphane böyle içine yöntemler girmiştik Array s’ GetLongLength bir döndüren, Int64 bir olan değeri uzun C gibi (diğer dillerde C # ancak ++ / CLI). Bir başka örnek ise System.Linq.Enumerable sitesindeki LongCount yöntemi.

Paragrafın tamamını okumadan önce fikrini alamadım.


72

String ( System.String), temel sınıf kitaplığındaki bir sınıftır. string (küçük harf) C # içinde System.String için bir diğer ad olan ayrılmış bir çalışmadır. Int32 vs int de benzer bir durumdur Boolean vs. bool. Bu C # diline özgü anahtar kelimeler, C'ye benzer bir stilde ilkelleri bildirmenize olanak tanır.


67

Stringbir anahtar kelime değildir ve Tanımlayıcı olarak kullanılabilirken stringbir anahtar kelime olup, Tanımlayıcı olarak kullanılamaz. Ve fonksiyon açısından her ikisi de aynıdır.


67

Gerçekten bir kongre meselesi. stringsadece C / C ++ stiline benziyor. Genel kural, seçtiğiniz dilin sağladığı kısayolları kullanmaktır (int / Int için Int32). Bu "nesne" için decimalde geçerlidir.

Teorik olarak bu, kodun "int" anlamına gelebilecek gelecekteki 64 bitlik bir standarda bağlanmasına yardımcı olabilir Int64, ancak bu nokta değildir ve herhangi bir yükseltme sihirbazının herhangi bir intreferansı Int32güvenli bir şekilde değiştirmesini beklerim.


66

Partiye geç geliyor: CLR tiplerini% 100 kullanıyorum (C # tipini kullanmaya zorlanmadığı sürece , ama son ne zaman olduğunu hatırlamıyorum).

Başlangıçta bu sene önce, Ritchie'nin CLR kitaplarına göre yapmaya başladım. Tüm CLR dillerinin nihayetinde CLR türleri kümesini destekleyebilmeleri mantıklıydı, bu yüzden CLR türlerini kullanarak kendiniz daha net ve muhtemelen daha fazla "yeniden kullanılabilir" kod sağladınız.

Şimdi bunu yıllardır yapıyorum, bu bir alışkanlık ve VS'nin CLR türleri için gösterdiği rengi seviyorum.

Tek gerçek downer, otomatik tamamlamanın C # türünü kullanmasıdır, bu nedenle CLR türünü belirtmek için otomatik olarak oluşturulan türleri yeniden yazarım.

Ayrıca, şimdi, "int" veya "string" i gördüğümde, 1970'lerin C koduna baktığımda bana çok yanlış geliyor.


49

Fark yok.

C # anahtar sözcüğü string.NET türüyle eşleşir System.String- dilin adlandırma kurallarını koruyan bir diğer addır.

Benzer şekilde, ile inteşleşir System.Int32.


64 bit derlemede int, System.Int64 (8 bayt) ile eşleşir, 32 bit derlemede System.Int32 (4 bayt) ile eşlenir
Alex

1
IntPtr ve UIntPtr, platforma göre boyutu değiştiren tek türlerdir ([U] IntPtr veya gerçek işaretçiler gibi gerçek işaretçi türlerini int*ve bunlardan oluşan türleri dikkate almaz).
P Daddy

45

Bu konuda Daniel Solis'in kitabından bir alıntı var .

Önceden tanımlanmış tüm türler doğrudan altta yatan .NET türleriyle eşlenir. C # türü adları (dize), .NET türleri (Dize veya System.String) için basitçe takma adlardır, bu nedenle, bu önerilmez, ancak .NET adlarını kullanmak sözdizimsel olarak iyi çalışır. Bir C # programında, .NET adları yerine C # adlarını kullanmalısınız.


41

string bir anahtar kelimedir ve string'i tanımlayıcı olarak kullanamazsınız.

Dize bir anahtar kelime değildir ve bunu tanımlayıcı olarak kullanabilirsiniz:

Misal

string String = "I am a string";

Anahtar kelime string , System.Stringanahtar kelime sorunundan başka bir takma addır, ikisi tam olarak eşdeğerdir.

 typeof(string) == typeof(String) == typeof(System.String)

2
Tek küçük fark, String sınıfını kullanıyorsanız, dosyanızın üstüne Sistem ad alanını içe aktarmanız gerektiğidir, ancak string anahtar sözcüğünü kullanırken bunu yapmak zorunda değilsiniz.
Uttam

Eşitlik ifadesinin başarısız olacağı basit kullanım durumları vardır ... Blah ad alanında bir tür çağrı çağrısı tanımlamak ve bu ad alanını eşitlik ifadesinin çalıştığı dosyaya aktarmak gibi.
rick


40

@JaredPar (C # derleyicisi ve üretken SO kullanıcısı üzerinde bir geliştirici!) Bu konuda harika bir blog yazısı yazdı . Bence burada paylaşmaya değer. Konumuzla ilgili güzel bir bakış açısı.

stringvs. Stringbir stil tartışması değildir

[...]

Anahtar kelimenin stringC # 'da somut bir anlamı vardır. System.StringÇekirdek çalışma zamanı derlemesinde bulunan türdür . Çalışma zamanı, bu türü özünde anlar ve geliştiricilerin .NET'te dizeler için beklediği yetenekleri sağlar. Varlığı C # için o kadar kritiktir ki, bu tür yoksa, derleyici bir kod satırını ayrıştırmaya çalışmadan önce çıkacaktır. Bu nedenle stringC # kodunda kesin, açık bir anlamı vardır.

Tanımlayıcının StringC # 'da somut bir anlamı yoktur. Bu gibi tüm İsmi arama kuralları geçer bir tanımlayıcı olan Widget, Studentvb ... Bu dizeye bağlamak olabilir ya da başka bir montaj tamamen, amaçları daha tamamen farklı olabilir bir tip bağlamak olabilir string. Daha kötüsü, kod gibi bir şekilde tanımlanabilir String s = "hello"; derlemeye devam etti.

class TricksterString { 
  void Example() {
    String s = "Hello World"; // Okay but probably not what you expect.
  }
}

class String {
  public static implicit operator String(string s) => null;
}

Gerçek anlamı Stringher zaman ad çözümlemesine bağlı olacaktır. Bu, projedeki tüm kaynak dosyalara ve başvurulan tüm derlemelerde tanımlanan tüm türlere bağlı olduğu anlamına gelir. Kısacası bunun ne anlama geldiğini bilmek biraz bağlam gerektirir .

Gerçek vakaların büyük çoğunluğunda olduğu Stringve stringaynı tip bağlanacaktır. Ancak Stringyine de kullanmak , geliştiricilerin programlarını tek bir doğru cevabın olduğu yerlerde yorumlamaya bıraktığı anlamına gelir. Ne zaman Stringyanlış tip bağlamak gelmez bu derleyici takımında hataları dosyalama ve genellikle kullanılarak kaydedilmiş olabilirdi zaman israf, saatlerce ayıklama geliştiriciler bırakabilir string.

Farkı görselleştirmenin başka bir yolu da bu örnektir:

string s1 = 42; // Errors 100% of the time  
String s2 = 42; // Might error, might not, depends on the code

Birçoğu, bu teknik olarak doğru bilgiler Stringolsa da, kod tabanının bu adın bir türünü tanımlaması son derece nadir olduğu için kullanımın hala iyi olduğunu iddia edecektir . Veya Stringtanımlandığında, kötü bir kod tabanının bir işareti.

[...]

Bunu göreceksiniz Stringbu kütüphaneler herhangi biri için ... vb yansıma yardımcıları, seri hale kütüphaneleri, lexers, protokoller: tamamen geçerli amaçlarla için tanımlanan Stringvs stringkod kullanıldığı yere bağlı olarak gerçek sonuçlar doğurur.

Tartışmaya Stringkarşı stringtartışmayı gördüğünüzde bunun tarz değil anlambilim ile ilgili olduğunu unutmayın. Dize seçmek, kod tabanınıza net bir anlam kazandırır. Seçim Stringyanlış değil ama gelecekte sürprizlere kapı açıyor.

Not: Blog gönderisinin çoğunu arşiv amacıyla kopyaladım / yapıştırdım. Bazı bölümleri görmezden geliyorum, bu yüzden atlayabilir ve mümkünse blog gönderisini okumanızı tavsiye ederim .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.