$ Dizeden önce ne anlama geliyor?


251

Ben kelimesi kelimesine dize kullanacaktım ama yanlışlıkla yazdınız $yerine @.

Ancak Derleyici bana herhangi bir Hata vermedi ve başarıyla Derlendi.

Ne olduğunu ve ne yaptığını bilmek istiyorum. Onu aradım ama hiçbir şey bulamadım.

Ancak yazamam çünkü bir sözcük dizesi gibi değil:

string str = $"text\";

Herkes $önce dize C # için ne anlama geldiğini biliyor mu .

string str = $"text";

Visual studio 2015 CTP kullanıyorum.

Yanıtlar:


419

$String.FormatC # 6'nın yeni bir özelliği olan dize enterpolasyonları için kısa ellidir ve kullanılır. Sizin durumunuzda kullanıldığı gibi string.Format()hiçbir şey yapmaz.

Diğer değerlere referansla dizeler oluşturmak için kullanıldığında kendi başına gelir. Daha önce şu şekilde yazılmak zorundaydı:

var anInt = 1;
var aBool = true;
var aString = "3";
var formated = string.Format("{0},{1},{2}", anInt, aBool, aString);

Şimdi olur:

var anInt = 1;
var aBool = true;
var aString = "3";
var formated = $"{anInt},{aBool},{aString}";

Alternatif olarak - daha az bilinen - dizi enterpolasyonu biçimi de vardır $@ (iki sembolün sırası önemlidir). Dize boyunca gerek kalmadan dize enterpolasyonlarını desteklemek @""için bir dizenin özelliklerinin karıştırılmasını sağlar . Yani aşağıdaki iki satır:$""\\

var someDir = "a";
Console.WriteLine($@"c:\{someDir}\b\c");

çıktı olacak:

c:\a\b\c

29
Gerçekten String.Format'ı kullanmadığını, ancak çalışma zamanı değil, derleyici tabanlı bir özellik olduğunu unutmayın.
Shahar Prish

2
Bugün öğrendiğim küçük bir not, eğer kullanırsanız $@, o "karakteri kullanarak karakterden kaçmak zorunda kalırsınız "". Sadece kullandığınızda durum böyle değil $.
flater

3
@Flater Bunun $ sembolü ile ilgisi yok. Bu, $ sembolü bulunmadan önceki davranışla aynıdır.
BVernon

2
Aynen (@) ve enterpolasyon ($) simge sıralamasının önemli olduğu noktaya gelince, bu C # 8'de düzeltilerek sıralamanın artık önemi kalmayacak. Bkz: devsanon.com/uncategorized/…
elkaz

39

Enterpolasyonlu bir dize oluşturur .

Gönderen MSDN

Dizeleri oluşturmak için kullanılır. Enterpolasyonlu dize ifadesi, ifadeler içeren bir şablon dizesine benzer. Enterpolasyonlu dize ifadesi, içerilen ifadeleri ifadelerin sonuçlarının ToString temsilleriyle değiştirerek bir dize oluşturur.

ör .:

 var name = "Sam";
 var msg = $"hello, {name}";

 Console.WriteLine(msg); // hello, Sam

Enterpolasyonlu dize içindeki ifadeleri kullanabilirsiniz

 var msg = $"hello, {name.ToLower()}";
 Console.WriteLine(msg); // hello, sam

Bununla ilgili güzel olan şey, parametrelerin sırası ile yaptığınız gibi endişelenmenize gerek olmamasıdır String.Format.

  var s = String.Format("{0},{1},{2}...{88}",p0,p1,..,p88);

Şimdi bazı parametreleri kaldırmak istiyorsanız, tüm sayıları güncellemeniz gerekiyor, bu artık geçerli değil.

Biçimlendirmenizdestring.format kültürel bilgi belirtmek istiyorsanız , iyi eserin hala alakalı olduğunu unutmayın .


$Verilerinizi $doğru kültürü kullanarak, örneğin ifadenin içindeki dizeye dönüştürürseniz, muhtemelen kültür bilgilerini kullanabileceğinizi ve belirtebileceğinizi unutmayın {somevar.ToString(...,[Insert culture info here])}.
jrh

18

Örnek Kod

public class Person {
    public String firstName { get; set; }
    public String lastName { get; set; }
}

// Instantiate Person
var person = new Person { firstName = "Albert", lastName = "Einstein" };

// We can print fullname of the above person as follows
Console.WriteLine("Full-Name - " + person.firstName + " " + person.lastName);
Console.WriteLine("Full-Name - {0} {1}", person.firstName, person.lastName);
Console.WriteLine($"Full-Name - {person.firstName} {person.lastName}");

Çıktı

Full-Name - Albert Einstein
Full-Name - Albert Einstein
Full-Name - Albert Einstein

Öyle Enterpole Strings . Bir dize hazır bilgisi kullanabileceğiniz her yerde enterpolasyonlu bir dize kullanabilirsiniz. Programınızı çalıştırdığınızda, kodu enterpolasyonlu dize değişmeziyle yürütürseniz, kod enterpolasyon ifadelerini değerlendirerek yeni bir dize değişmezini hesaplar. Bu hesaplama, enterpolasyonlu dize ile kod her yürütüldüğünde gerçekleşir.

Aşağıdaki örnek, tüm dize enterpolasyon değerlerinin hesaplandığı bir dize değeri üretir. Nihai sonuçtur ve type dizesine sahiptir. Çift kıvrımlı parantezlerin tüm oluşumları (“{{“ and “}}”)tek bir kıvrık ayraca dönüştürülür.

string text = "World";
var message = $"Hello, {text}";

2 satırın üzerinde yürüttükten sonra, değişken message"Merhaba, Dünya" içerir.

Console.WriteLine(message); // Prints Hello, World

Referans - MSDN


10

Harika özellik. Ben sadece bu string.format neden bazı insanlar için belirgin değilse neden daha iyi vurgulamak istiyorum.

Parametreleri eşleştirmek için "{0} {1} {2}" düzenine string.format diyen birini okudum. String.format içinde "{0} {1} {2}" sipariş etmek zorunda değilsiniz, "{2} {0} {1}" de yapabilirsiniz. Ancak, 20 gibi çok sayıda parametreniz varsa, dizeyi gerçekten "{0} {1} {2} ... {19}" olarak sıralamak istersiniz. Karışık bir karmaşa ise, parametrelerinizi sıralamakta zorlanırsınız.

$ İle parametrelerinizi saymadan satır içi parametre ekleyebilirsiniz. Bu, kodun okunmasını ve bakımını çok daha kolay hale getirir.

$ Dezavantajı, parametreyi dizede kolayca tekrarlayamazsınız, yazmanız gerekir. Örneğin, System.Environment.NewLine yazmaktan sıkıldıysanız string.format ("... {0} ... {0} ... {0}", System.Environment.NewLine), ancak, $ cinsinden tekrarlamanız gerekir. $ "{0}" yapamazsınız ve $ "{0}", "0" döndürdüğü için string.format'a iletemezsiniz.

Yan notta, başka bir yinelenen tpoic yorum okudum. Yorum yapamadım, işte burada. Dedi ki

string msg = n + " sheep, " + m + " chickens";

birden fazla dize nesnesi oluşturur. Aslında bu doğru değil. Bunu tek bir satırda yaparsanız, yalnızca bir dize oluşturur ve dize önbelleğine yerleştirilir.

1) string + string + string + string;
2) string.format()
3) stringBuilder.ToString()
4) $""

Hepsi bir dize döndürür ve önbellekte yalnızca bir değer oluşturur.

Diğer yandan:

string+= string2;
string+= string2;
string+= string2;
string+= string2;

4 ";" olduğundan önbellekte 4 farklı değer oluşturur.

Böylece, aşağıdaki gibi kod yazmak daha kolay olacaktır, ancak Carlos Muñoz'ın düzelttiği gibi beş enterpolasyonlu dize oluşturacaksınız:

string msg = $"Hello this is {myName}, " +
  $"My phone number {myPhone}, " +
  $"My email {myEmail}, " +
  $"My address {myAddress}, and " +
  $"My preference {myPreference}.";

Bu, kodu okumak çok kolayken önbellekte tek bir dize oluşturur. Performans hakkında emin değilim, ama eminim MS zaten yapmazsa onu optimize edecek.


1
Son örneğiniz yanlış: Aslında iki dizgi oluşturuyorsunuz: Biri enterpolasyonlu dizeden, diğeri dizelerin geri kalanından. Yalnızca {myName} olanın enterpolasyona uğradığına, diğerlerinin beklendiği gibi çalışmadığına dikkat edin.
Carlos Muñoz

1
Ve $ dizesini 5 dizeye eklerseniz, o zaman her biri kendi ile enterpolasyonlu dizeler oluşturur String.Format()ve daha sonra çalışma zamanında birleştirilir String.Concat. Bu yüzden birden fazla satıra
Carlos Muñoz

1
Haklısın @Carlos Muñoz, düzelttim. Hatayı yakaladığınız için teşekkürler.
BoBoDev

8

Oldukça serin olan ikisini de birleştirebileceğinizi unutmayın (biraz garip görünse de):

// simple interpolated verbatim string
WriteLine($@"Path ""C:\Windows\{file}"" not found.");

5
Eğer yazdığınız sıraya sadece karar verebilseydiniz $@ya da @$. Ne yazık ki sadece olabilir$@
Bauss

2
@Bauss Bu mantıklı. @dizgi değişmezinin nasıl temsil edileceğini tanımlar. $için bir kısayoldur string.Format. Düşünün$(@"");
marsze

Gerçekten bir kısayol değil string.Format. Bir değerine ayrıştırılan bir değer sunmak şeklidir string.Format, bu yüzden kısmen mantıklıdır, ancak tamamen değil.
Bauss

3
Diyorum ki $, temelde bir zımni fonksiyon çağrısıdır, oysa ondalık bir değişmezdeki @gibi, kelimenin tam anlamıyla bir parçasıdır m. Bu yüzden sadece bir mantıklı düzen var.
marsze

2
Bunun çoğunlukla göstermek $için burada olduğunu biliyorum , ancak maksimum uyumluluk ve dizin ayırıcısının '/' veya '\' olup olmadığını ve ayrıca çift eğik çizgiye veya eksik eğik çizgiye neden olan kaçınılmaz vidadan kaçınmak için zor kodlama değil biri olmuştur, Path.Combine()dizinler ve dosyalarla çalışırken dize birleştirme kullanmak yerine kullanmanızı öneririz .
jrh

6

Format ve burada da intellisense kullanabilirsiniz.

resim açıklamasını buraya girin

İşte benim test yöntemim:

[TestMethod]
public void StringMethodsTest_DollarSign()
{
    string name = "Forrest";
    string surname = "Gump";
    int year = 3; 
    string sDollarSign = $"My name is {name} {surname} and once I run more than {year} years."; 
    string expectedResult = "My name is Forrest Gump and once I run more than 3 years."; 
    Assert.AreEqual(expectedResult, sDollarSign);
}

6

Dize enterpolasyonunu ifade eder.

Dize değerlendirmesine derleme zamanı koruması eklediğinden sizi koruyacaktır.

Artık bir istisna alamayacaksınız string.Format("{0}{1}",secondParamIsMissing)


6

Aşağıdaki örnek string.Format(), temizlik ve okunabilirlik açısından enterpolasyonlu dizelerin kullanılmasının çeşitli avantajlarını vurgulamaktadır . Ayrıca, içindeki kodun {}, string.Format()çağrıldığımız gibi, diğer işlev argümanları gibi değerlendirildiğini de gösterir .

using System;

public class Example
{
   public static void Main()
   {
      var name = "Horace";
      var age = 34;
      // replaces {name} with the value of name, "Horace"
      var s1 = $"He asked, \"Is your name {name}?\", but didn't wait for a reply.";
      Console.WriteLine(s1);

      // as age is an integer, we can use ":D3" to denote that
      // it should have leading zeroes and be 3 characters long
      // see https://docs.microsoft.com/en-us/dotnet/standard/base-types/how-to-pad-a-number-with-leading-zeros
      //
      // (age == 1 ? "" : "s") uses the ternary operator to 
      // decide the value used in the placeholder, the same 
      // as if it had been placed as an argument of string.Format
      //
      // finally, it shows that you can actually have quoted strings within strings
      // e.g. $"outer { "inner" } string"
      var s2 = $"{name} is {age:D3} year{(age == 1 ? "" : "s")} old.";
      Console.WriteLine(s2); 
   }
}
// The example displays the following output:
//       He asked, "Is your name Horace?", but didn't wait for a reply.
//       Horace is 034 years old.

6

$ sözdizimi güzel, ama bir dezavantajı ile.

Dize şablonu gibi bir şeye ihtiyacınız varsa, sınıf düzeyinde alan olarak bildirilir ... olması gerektiği gibi tek bir yerde.

O zaman değişkenleri aynı seviyede beyan etmelisiniz ... ki bu gerçekten hoş değil.

Bu tür şeyler için format sözdizimini kullanmak çok daha hoştur.

class Example1_StringFormat {
 string template = $"{0} - {1}";

 public string FormatExample1() {
   string some1 = "someone";
   return string.Format(template, some1, "inplacesomethingelse");
 }

 public string FormatExample2() {
   string some2 = "someoneelse";
   string thing2 = "somethingelse";
   return string.Format(template, some2, thing2);
 }
}

Küresellerin kullanımı gerçekten iyi değil ve bunun yanı sıra - küresellerle de çalışmıyor

 static class Example2_Format {
 //must have declaration in same scope
 static string some = "";
 static string thing = "";
 static string template = $"{some} - {thing}";

//This returns " - " and not "someone - something" as you would maybe 
//expect
 public static string FormatExample1() {
   some = "someone";
   thing = "something";
   return template;
 }

//This returns " - " and not "someoneelse- somethingelse" as you would 
//maybe expect
 public static string FormatExample2() {
   some = "someoneelse";
   thing = "somethingelse";
   return template;
 }
}

Bu yanıt, enterpolasyonun bildirdiğinizde değil, $ dizesini "çağırdığınızda" gerçekleştiğine işaret ettiği için önemlidir.
dx_over_dt

1
Sınıf kapsamındaki enterpolasyon değişkenlerinizi bildirme biçiminde haklısınız, ancak bu değişkenler zaten sınıf özellikleri olarak aitse , bu model iyi çalışır.
dx_over_dt

@dx_over_dt Yanılıyorsunuz. Enterpolasyonlu dizeler bildirildikleri sırada değerlendirilir. Bu yüzden örnek kodun bir anlamı yok. Ayrıca derlenmeyecektir.
NineBerry

@NineBerry Hem de enterpolasyonlu dizeleri bildirildikleri anda değerlendirilir doğru ve hakkında Örnek_ $ Biçimi derlemiyor ve örnek kodu hakkında mantıklı değil :) Daha iyi açıklamak için örnek düzelttik.
Tom


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.