Dizeler ve dize değişmez değerleri

Dize, değeri metin olan türünde String bir nesnedir. Dahili olarak, metin sıralı salt okunur bir nesne koleksiyonu Char olarak depolanır. C# dizesinin sonunda null sonlandırıcı karakter yoktur; bu nedenle bir C# dizesi herhangi bir sayıda eklenmiş null karakter ('\0') içerebilir. Length Bir dizenin özelliği, Unicode karakter sayısını Char değil içerdiği nesne sayısını temsil eder. Bir dizedeki tek tek Unicode kod noktalarına erişmek için nesnesini kullanın StringInfo .

dize ve System.String karşılaştırması

C# dilinde string anahtar sözcüğü için Stringbir diğer addır. Bu nedenle ve Stringstring eşdeğerdir, ne olursa olsun, sağlanan diğer adı string olmadan using System;bile çalıştığından kullanmanız önerilir. sınıfı String , dizeleri güvenli bir şekilde oluşturmak, işlemek ve karşılaştırmak için birçok yöntem sağlar. Ayrıca, C# dili yaygın dize işlemlerini basitleştirmek için bazı işleçleri aşırı yükler. Anahtar sözcüğü hakkında daha fazla bilgi için bkz. dize. Türü ve yöntemleri hakkında daha fazla bilgi için bkz String. .

Dizeleri bildirme ve başlatma

Aşağıdaki örnekte gösterildiği gibi dizeleri çeşitli yollarla bildirebilir ve başlatabilirsiniz:

// Declare without initializing.
string message1;

// Initialize to null.
string message2 = null;

// Initialize as an empty string.
// Use the Empty constant instead of the literal "".
string message3 = System.String.Empty;

// Initialize with a regular string literal.
string oldPath = "c:\\Program Files\\Microsoft Visual Studio 8.0";

// Initialize with a verbatim string literal.
string newPath = @"c:\Program Files\Microsoft Visual Studio 9.0";

// Use System.String if you prefer.
System.String greeting = "Hello World!";

// In local variables (i.e. within a method body)
// you can use implicit typing.
var temp = "I'm still a strongly-typed System.String!";

// Use a const string to prevent 'message4' from
// being used to store another string value.
const string message4 = "You can't get rid of me!";

// Use the String constructor only when creating
// a string from a char*, char[], or sbyte*. See
// System.String documentation for details.
char[] letters = { 'A', 'B', 'C' };
string alphabet = new string(letters);

Dizeyi karakter dizisiyle başlatma dışında bir dize nesnesi oluşturmak için yeni işlecini kullanmazsınız.

Dize uzunluğu Empty sıfır olan yeni String bir nesne oluşturmak için sabit değere sahip bir dize başlatın. Sıfır uzunluklu bir dizenin dize değişmez değeri gösterimi ""dir. Dizeleri null yerine değerle Empty başlatarak, gerçekleşme olasılığını NullReferenceException azaltabilirsiniz. Erişmeye çalışmadan önce bir dizenin değerini doğrulamak için statik IsNullOrEmpty(String) yöntemini kullanın.

Dizelerin değişmezliği

Dize nesneleri sabittir: oluşturulduktan sonra değiştirilemezler. Bir dizeyi String değiştirmek için görünen tüm yöntemler ve C# işleçleri aslında sonuçları yeni bir dize nesnesinde döndürür. Aşağıdaki örnekte ve s2 içindekiler s1 tek bir dize oluşturacak şekilde birleştirildiğinde, iki özgün dize değiştirilmez. işleci, += birleştirilmiş içerikleri içeren yeni bir dize oluşturur. Bu yeni nesne değişkenine s1atanır ve kendisine atanan s1 özgün nesne çöp toplama için serbest bırakılır çünkü başka hiçbir değişken buna başvuru tutmaz.

string s1 = "A string is more ";
string s2 = "than the sum of its chars.";

// Concatenate s1 and s2. This actually creates a new
// string object and stores it in s1, releasing the
// reference to the original object.
s1 += s2;

System.Console.WriteLine(s1);
// Output: A string is more than the sum of its chars.

Dize "değişikliği" aslında yeni bir dize oluşturma olduğundan, dizelere başvuru oluştururken dikkatli olmanız gerekir. Bir dizeye başvuru oluşturur ve sonra özgün dizeyi "değiştirirseniz" başvuru, dize değiştirildiğinde oluşturulan yeni nesne yerine özgün nesneyi işaret etmeye devam eder. Aşağıdaki kodda bu davranış gösterilmektedir:

string str1 = "Hello ";
string str2 = str1;
str1 += "World";

System.Console.WriteLine(str2);
//Output: Hello

Özgün dizede arama ve değiştirme işlemleri gibi değişiklikleri temel alan yeni dizeler oluşturma hakkında daha fazla bilgi için bkz. Dize içeriğini değiştirme.

Alıntılı dize değişmez değerleri

Tırnak içine alınmış dize değişmez değerleri , aynı satırda tek bir çift tırnak karakteriyle (") başlayıp biter. Tırnak içine alınmış dize değişmez değerleri, tek bir satıra sığan ve kaçış dizileri içermeyen dizeler için en uygun seçenektir. Tırnak içine alınmış dize değişmez değeri, aşağıdaki örnekte gösterildiği gibi kaçış karakterleri eklemelidir:

string columns = "Column 1\tColumn 2\tColumn 3";
//Output: Column 1        Column 2        Column 3

string rows = "Row 1\r\nRow 2\r\nRow 3";
/* Output:
    Row 1
    Row 2
    Row 3
*/

string title = "\"The \u00C6olean Harp\", by Samuel Taylor Coleridge";
//Output: "The Æolean Harp", by Samuel Taylor Coleridge

Düz metin dizesi değişmez değerleri

Düz metin dizesi değişmez değerleri , çok satırlı dizeler, ters eğik çizgi karakterleri içeren dizeler veya eklenmiş çift tırnak işaretleri için daha kullanışlıdır. Düz metin dizeleri, dize metninin bir parçası olarak yeni satır karakterlerini korur. Düz metin dizesinin içine tırnak işareti eklemek için çift tırnak işareti kullanın. Aşağıdaki örnekte, düz metin dizeleri için bazı yaygın kullanımlar gösterilmektedir:

string filePath = @"C:\Users\scoleridge\Documents\";
//Output: C:\Users\scoleridge\Documents\

string text = @"My pensive SARA ! thy soft cheek reclined
    Thus on mine arm, most soothing sweet it is
    To sit beside our Cot,...";
/* Output:
My pensive SARA ! thy soft cheek reclined
    Thus on mine arm, most soothing sweet it is
    To sit beside our Cot,...
*/

string quote = @"Her name was ""Sara.""";
//Output: Her name was "Sara."

Ham dize değişmez değerleri

C# 11'den başlayarak, ham dize değişmez değerlerini kullanarak çok satırlı dizeleri daha kolay oluşturabilir veya kaçış dizileri gerektiren herhangi bir karakteri kullanabilirsiniz. Ham dize değişmez değerleri , kaçış dizilerini kullanma gereksinimini ortadan kaldırır. Dizeyi, boşluk biçimlendirmesi ve çıkışta görünmesini istediğiniz şekilde yazabilirsiniz. Ham dize değişmez değeri:

  • En az üç çift tırnak karakteri (""" ) dizisiyle başlar ve biter. Üç (veya daha fazla) yinelenen tırnak karakteri içeren dize değişmez değerlerini desteklemek için sırayı üçten fazla ardışık karakter başlatmanıza ve sonlandırmanıza izin verilir.
  • Tek satırlı ham dize değişmez değerleri, aynı satırda açma ve kapatma tırnak işareti karakterlerini gerektirir.
  • Çok satırlı ham dize değişmez değerleri, kendi satırlarında hem açma hem de kapatma tırnak işaretleri gerektirir.
  • Çok satırlı ham dize değişmez değerlerinde, kapanış tırnaklarının solundaki tüm boşluklar kaldırılır.

Aşağıdaki örneklerde bu kurallar gösterilmektedir:

string singleLine = """Friends say "hello" as they pass by.""";
string multiLine = """
    "Hello World!" is typically the first program someone writes.
    """;
string embeddedXML = """
       <element attr = "content">
           <body style="normal">
               Here is the main text
           </body>
           <footer>
               Excerpts from "An amazing story"
           </footer>
       </element >
       """;
// The line "<element attr = "content">" starts in the first column.
// All whitespace left of that column is removed from the string.

string rawStringLiteralDelimiter = """"
    Raw string literals are delimited 
    by a string of at least three double quotes,
    like this: """
    """";

Aşağıdaki örneklerde, bu kurallara göre bildirilen derleyici hataları gösterilmektedir:

// CS8997: Unterminated raw string literal.
var multiLineStart = """This
    is the beginning of a string 
    """;

// CS9000: Raw string literal delimiter must be on its own line.
var multiLineEnd = """
    This is the beginning of a string """;

// CS8999: Line does not start with the same whitespace as the closing line
// of the raw string literal
var noOutdenting = """
    A line of text.
Trying to outdent the second line.
    """;

Çok satırlı ham dize değişmez değerleri kendi satırında tırnak açma ve kapatma sırasını gerektirdiğinden ilk iki örnek geçersizdir. Üçüncü örnek geçersiz çünkü metnin girintisi kapanış tırnak işareti dizisinden azaltıldı.

Tırnak içine alınmış dize değişmez değerleri veya düz metin dize değişmez değerleri kullanırken kaçış dizileri gerektiren karakterler içeren metin oluştururken ham dize değişmez değerlerini dikkate almanız gerekir. Ham dize değişmez değerleri sizin ve başkalarının okuması daha kolay olacaktır çünkü çıkış metnine daha yakın olacaktır. Örneğin, biçimlendirilmiş JSON dizesi içeren aşağıdaki kodu göz önünde bulundurun:

string jsonString = """
{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "Hot",
  "DatesAvailable": [
    "2019-08-01T00:00:00-07:00",
    "2019-08-02T00:00:00-07:00"
  ],
  "TemperatureRanges": {
    "Cold": {
      "High": 20,
      "Low": -10
    },
    "Hot": {
      "High": 60,
      "Low": 20
    }
            },
  "SummaryWords": [
    "Cool",
    "Windy",
    "Humid"
  ]
}
""";

Bu metni, bu yeni özelliği kullanmayan JSON serileştirme örneğimizdeki eşdeğer metinle karşılaştırın.

Dize kaçış dizileri

Kaçış dizisi Karakter adı Unicode kodlama
\' Tek tırnak 0x0027
\" Çift tırnak 0x0022
\\ Ters eğik çizgi 0x005C
\0 Null 0x0000
\a Uyarı 0x0007
\b Geri Al tuşu 0x0008
\f Form akışı 0x000C
\n Yeni satır 0x000A
\r Satır başı 0x000D
\t Yatay sekme 0x0009
\v Dikey sekme 0x000B
\u Unicode kaçış dizisi (UTF-16) \uHHHH (aralık: 0000 - FFFF; örnek: \u00E7 = "ç")
\U Unicode kaçış dizisi (UTF-32) \U00HHHHHH (aralık: 000000 - 10FFFF; örnek: \U0001F47D = "👽")
\x Değişken uzunluğu dışında "\u" benzeri Unicode kaçış dizisi \xH[H][H][H] (aralık: 0 - FFFF; örnek: \x00E7 veya \x0E7 = \xE7 "ç")

Uyarı

Kaçış dizisini \x kullanırken ve 4 onaltılık basamaktan azını belirtirken, kaçış dizisini hemen izleyen karakterler geçerli onaltılık basamaklar (0-9, A-F ve a-f) ise, kaçış dizisinin bir parçası olarak yorumlanırlar. Örneğin, \xA1 U+00A1 kod noktası olan ""yi üretir. Ancak, sonraki karakter "A" veya "a" ise, kaçış dizisi bunun yerine" olarak \xA1A yorumlanır ve U+0A1A kod noktası olan "ਚ" oluşturur. Böyle durumlarda, 4 onaltılık basamağın tümünün (örn. \x00A1 ) belirtilmesi olası yanlış yorumlamayı önler.

Not

Derleme zamanında, düz metin dizeleri aynı kaçış dizileriyle normal dizelere dönüştürülür. Bu nedenle, hata ayıklayıcısı izleme penceresinde bir tamsayı dizesini görüntülerseniz, kaynak kodunuzdan gelen tamsayı sürümünü değil derleyici tarafından eklenen kaçış karakterlerini görürsünüz. Örneğin, açıklama dizesi @"C:\files.txt" izleme penceresinde "C:\\files.txt" olarak görünür.

Dizeleri biçimlendirme

Biçim dizesi, çalışma zamanında içeriği dinamik olarak belirlenen bir dizedir. Biçim dizeleri, bir dize içindeki küme ayraçlarının içine ilişkilendirilmiş ifadeler veya yer tutucular eklenerek oluşturulur. Küme ayraçları ({...}) içindeki her şey bir değere çözümlenir ve çalışma zamanında biçimlendirilmiş bir dize olarak çıkar. Biçim dizeleri oluşturmak için iki yöntem vardır: dize ilişkilendirmesi ve bileşik biçimlendirme.

Dize ilişkilendirme

C# 6.0 ve sonraki sürümlerde kullanılabilir, ilişkilendirilmiş dizeler özel karakter tarafından $ tanımlanır ve ayraçlara ilişkilendirilmiş ifadeler ekler. Dize ilişkilendirmeyi yeni kullanıyorsanız hızlı bir genel bakış için Dize ilişkilendirme - C# etkileşimli öğreticisine bakın.

Kodunuzun okunabilirliğini ve sürdürülebilirliğini geliştirmek için dize ilişkilendirmesini kullanın. Dize ilişkilendirme yöntemiyle aynı sonuçları String.Format elde eder, ancak kullanım kolaylığını ve satır içi netliği artırır.

var jh = (firstName: "Jupiter", lastName: "Hammon", born: 1711, published: 1761);
Console.WriteLine($"{jh.firstName} {jh.lastName} was an African American poet born in {jh.born}.");
Console.WriteLine($"He was first published in {jh.published} at the age of {jh.published - jh.born}.");
Console.WriteLine($"He'd be over {Math.Round((2018d - jh.born) / 100d) * 100d} years old today.");

// Output:
// Jupiter Hammon was an African American poet born in 1711.
// He was first published in 1761 at the age of 50.
// He'd be over 300 years old today.

C# 10 ile başlayarak, yer tutucular için kullanılan tüm ifadeler de sabit dizeler olduğunda sabit bir dize başlatmak için dize ilişkilendirmesini kullanabilirsiniz.

C# 11'den başlayarak , ham dize değişmez değerlerini dize ilişkilendirmeleriyle birleştirebilirsiniz. Biçim dizesini üç veya daha fazla ardışık çift tırnakla başlatır ve sonlarsınız. Çıkış dizeniz veya } karakterini içermeliyse, bir ilişkilendirmenin { kaç { ve } karakter başlatıp biteceğini belirtmek için fazladan $ karakterler kullanabilirsiniz. Daha az { veya } karakterden oluşan herhangi bir dizi çıkışa eklenir. Aşağıdaki örnekte, bir noktanın çıkış noktasından uzaklığı görüntülemek ve noktayı küme ayraçlarının içine yerleştirmek için bu özelliği nasıl kullanabileceğiniz gösterilmektedir:

int X = 2;
int Y = 3;

var pointMessage = $$"""The point {{{X}}, {{Y}}} is {{Math.Sqrt(X * X + Y * Y)}} from the origin.""";

Console.WriteLine(pointMessage);
// Output:
// The point {2, 3} is 3.605551275463989 from the origin.

Bileşik biçimlendirme

, String.Format biçim dizesi oluşturmak için küme ayraçlarındaki yer tutucuları kullanır. Bu örnek, yukarıda kullanılan dize ilişkilendirme yöntemine benzer bir çıkışla sonuç verir.

var pw = (firstName: "Phillis", lastName: "Wheatley", born: 1753, published: 1773);
Console.WriteLine("{0} {1} was an African American poet born in {2}.", pw.firstName, pw.lastName, pw.born);
Console.WriteLine("She was first published in {0} at the age of {1}.", pw.published, pw.published - pw.born);
Console.WriteLine("She'd be over {0} years old today.", Math.Round((2018d - pw.born) / 100d) * 100d);

// Output:
// Phillis Wheatley was an African American poet born in 1753.
// She was first published in 1773 at the age of 20.
// She'd be over 300 years old today.

.NET türlerini biçimlendirme hakkında daha fazla bilgi için bkz. .NET'te Biçimlendirme Türleri.

Alt Dizeler

Alt dize, bir dizede yer alan herhangi bir karakter dizisidir. Özgün dizenin Substring bir bölümünden yeni bir dize oluşturmak için yöntemini kullanın. yöntemini kullanarak bir alt dizenin bir veya daha fazla örneğini IndexOf arayabilirsiniz. Replace Belirtilen alt dizenin tüm oluşumlarını yeni bir dizeyle değiştirmek için yöntemini kullanın. Substring yöntemi gibi, Replace aslında yeni bir dize döndürür ve özgün dizeyi değiştirmez. Daha fazla bilgi için bkz. Dizeleri arama ve Dize içeriğini değiştirme.

string s3 = "Visual C# Express";
System.Console.WriteLine(s3.Substring(7, 2));
// Output: "C#"

System.Console.WriteLine(s3.Replace("C#", "Basic"));
// Output: "Visual Basic Express"

// Index values are zero-based
int index = s3.IndexOf("C");
// index = 7

Tek tek karakterlere erişme

Aşağıdaki örnekte olduğu gibi, tek tek karakterlere salt okunur erişim elde etmek için dizin değeriyle dizi gösterimini kullanabilirsiniz:

string s5 = "Printing backwards";

for (int i = 0; i < s5.Length; i++)
{
    System.Console.Write(s5[s5.Length - i - 1]);
}
// Output: "sdrawkcab gnitnirP"

Yöntemler bir dizedeki String karakterleri tek tek değiştirmek için gereken işlevselliği sağlamıyorsa, tek tek karakterleri "yerinde" değiştirmek için bir StringBuilder nesnesi kullanabilir ve ardından yöntemleri kullanarak StringBuilder sonuçları depolamak için yeni bir dize oluşturabilirsiniz. Aşağıdaki örnekte, özgün dizeyi belirli bir şekilde değiştirmeniz ve ardından sonuçları gelecekte kullanmak üzere depolamanız gerektiğini varsayalım:

string question = "hOW DOES mICROSOFT wORD DEAL WITH THE cAPS lOCK KEY?";
System.Text.StringBuilder sb = new System.Text.StringBuilder(question);

for (int j = 0; j < sb.Length; j++)
{
    if (System.Char.IsLower(sb[j]) == true)
        sb[j] = System.Char.ToUpper(sb[j]);
    else if (System.Char.IsUpper(sb[j]) == true)
        sb[j] = System.Char.ToLower(sb[j]);
}
// Store the new string.
string corrected = sb.ToString();
System.Console.WriteLine(corrected);
// Output: How does Microsoft Word deal with the Caps Lock key?

Null dizeler ve boş dizeler

Boş dize, sıfır karakter içeren bir System.String nesne örneğidir. Boş dizeler genellikle çeşitli programlama senaryolarında boş bir metin alanını temsil etmek için kullanılır. Geçerli System.String nesneler olduğundan boş dizelerde yöntemleri çağırabilirsiniz. Boş dizeler aşağıdaki gibi başlatılır:

string s = String.Empty;

Buna karşılık, null dize bir System.String nesnenin örneğine başvurmaz ve null dizede yöntem çağırma girişimleri bir NullReferenceExceptionöğesine neden olur. Ancak, diğer dizelerle birleştirme ve karşılaştırma işlemlerinde null dizeler kullanabilirsiniz. Aşağıdaki örneklerde, null dizeye yapılan başvurunun özel durum oluşturmasına neden olmadığı bazı durumlar gösterilmektedir:

string str = "hello";
string nullStr = null;
string emptyStr = String.Empty;

string tempStr = str + nullStr;
// Output of the following line: hello
Console.WriteLine(tempStr);

bool b = (emptyStr == nullStr);
// Output of the following line: False
Console.WriteLine(b);

// The following line creates a new empty string.
string newStr = emptyStr + nullStr;

// Null strings and empty strings behave differently. The following
// two lines display 0.
Console.WriteLine(emptyStr.Length);
Console.WriteLine(newStr.Length);
// The following line raises a NullReferenceException.
//Console.WriteLine(nullStr.Length);

// The null character can be displayed and counted, like other chars.
string s1 = "\x0" + "abc";
string s2 = "abc" + "\x0";
// Output of the following line: * abc*
Console.WriteLine("*" + s1 + "*");
// Output of the following line: *abc *
Console.WriteLine("*" + s2 + "*");
// Output of the following line: 4
Console.WriteLine(s2.Length);

Hızlı dize oluşturma için stringBuilder kullanma

.NET'teki dize işlemleri yüksek oranda iyileştirilir ve çoğu durumda performansı önemli ölçüde etkilemez. Ancak, yüzlerce veya binlerce kez yürütülen sıkı döngüler gibi bazı senaryolarda dize işlemleri performansı etkileyebilir. sınıfı, StringBuilder programınız birçok dize işlemesi gerçekleştirirse daha iyi performans sunan bir dize arabelleği oluşturur. Dize StringBuilder ayrıca yerleşik dize veri türünün desteklemediği tek tek karakterleri yeniden atamanızı sağlar. Örneğin bu kod, yeni bir dize oluşturmadan bir dizenin içeriğini değiştirir:

System.Text.StringBuilder sb = new System.Text.StringBuilder("Rat: the ideal pet");
sb[0] = 'C';
System.Console.WriteLine(sb.ToString());
//Outputs Cat: the ideal pet

Bu örnekte, bir StringBuilder sayısal tür kümesinden dize oluşturmak için bir nesne kullanılır:

var sb = new StringBuilder();

// Create a string composed of numbers 0 - 9
for (int i = 0; i < 10; i++)
{
    sb.Append(i.ToString());
}
Console.WriteLine(sb);  // displays 0123456789

// Copy one character of the string (not possible with a System.String)
sb[0] = sb[9];

Console.WriteLine(sb);  // displays 9123456789

Dizeler, uzantı yöntemleri ve LINQ

String türü uyguladığındanIEnumerable<T>, dizelerde sınıfında tanımlanan Enumerable uzantı yöntemlerini kullanabilirsiniz. Görsel dağınıklığı önlemek için bu yöntemler türü için String IntelliSense'in dışında tutulur, ancak yine de kullanılabilir. Dizelerde LINQ sorgu ifadelerini de kullanabilirsiniz. Daha fazla bilgi için bkz. LINQ ve Strings.