Apa maksud $ sebelum string?


250

Saya akan menggunakan string verbatim tetapi saya keliru diketik $bukan @.

Tetapi Compiler tidak memberi saya Kesalahan dan Kompilasi berhasil.

Saya ingin tahu apa itu dan apa fungsinya. Saya mencarinya tetapi saya tidak dapat menemukan apa pun.

Namun tidak seperti string kata demi kata karena saya tidak dapat menulis:

string str = $"text\";

Apakah ada yang tahu apa yang $sebelum string berdiri dalam C #.

string str = $"text";

Saya menggunakan Visual studio 2015 CTP.

Jawaban:


418

$pendek untuk String.Formatdan digunakan dengan interpolasi string, yang merupakan fitur baru dari C # 6. Seperti yang digunakan dalam kasus Anda, itu tidak melakukan apa-apa, sama seperti string.Format()tidak melakukan apa-apa.

Ini menjadi miliknya sendiri ketika digunakan untuk membangun string dengan mengacu pada nilai-nilai lain. Apa yang sebelumnya harus ditulis sebagai:

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

Sekarang menjadi:

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

Ada juga alternatif - kurang terkenal - bentuk interpolasi string menggunakan $@ (urutan kedua simbol itu penting). Ini memungkinkan fitur-fitur @""string untuk dicampurkan dengan $""untuk mendukung interpolasi string tanpa perlu untuk \\seluruh string Anda. Jadi dua baris berikut:

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

akan menampilkan:

c:\a\b\c

29
Perhatikan bahwa itu tidak benar-benar menggunakan String.Format, tetapi merupakan fitur berbasis compiler, bukan runtime.
Shahar Prish

2
Catatan kecil yang saya pelajari hari ini, jika Anda gunakan $@, maka Anda terpaksa keluar dari "karakter dengan menggunakan "". Ini tidak terjadi ketika Anda hanya menggunakan $.
Flater

3
@Flater Itu tidak ada hubungannya dengan simbol $ sekalipun. Itu perilaku yang sama seperti sebelum simbol $ ada.
BVernon

2
Untuk poin Anda tentang urutan urutan kata demi kata (@) dan interpolasi ($) menjadi penting, ini sedang diperbaiki di C # 8 sehingga pemesanan tidak lagi menjadi masalah. Lihat: devsanon.com/uncategorized/…
elkaz

38

Ini menciptakan string yang diinterpolasi .

Dari MSDN

Digunakan untuk membangun string. Ekspresi string terinterpolasi tampak seperti string template yang berisi ekspresi. Ekspresi string terinterpolasi menciptakan string dengan mengganti ekspresi yang terkandung dengan representasi ToString dari hasil ekspresi.

mis:

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

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

Anda dapat menggunakan ekspresi dalam string yang diinterpolasi

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

Yang menyenangkan tentang itu adalah Anda tidak perlu khawatir tentang urutan parameter seperti yang Anda lakukan String.Format.

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

Sekarang jika Anda ingin menghapus beberapa parameter Anda harus pergi dan memperbarui semua penghitungan, yang tidak lagi berlaku.

Perhatikan bahwa barang lama string.formatmasih relevan jika Anda ingin menentukan info budaya dalam pemformatan Anda .


Perhatikan bahwa Anda mungkin masih dapat menggunakan $dan menentukan info kultur jika Anda mengonversi data ke string di dalam $ekspresi menggunakan kultur yang benar, misalnya {somevar.ToString(...,[Insert culture info here])},.
jrh

18

Kode Contoh

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}");

Keluaran

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

Ini adalah String Interpolasi . Anda dapat menggunakan string interpolasi di mana saja Anda bisa menggunakan string literal. Saat menjalankan program Anda akan mengeksekusi kode dengan string literal interpolasi, kode menghitung string literal baru dengan mengevaluasi ekspresi interpolasi. Komputasi ini terjadi setiap kali kode dengan string interpolasi dieksekusi.

Contoh berikut menghasilkan nilai string di mana semua nilai interpolasi string telah dihitung. Ini adalah hasil akhir dan memiliki tipe string. Semua kejadian kurung kurawal ganda (“{{“ and “}}”)dikonversi menjadi kurawal kurawal tunggal.

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

Setelah mengeksekusi di atas 2 baris, variabel messageberisi "Halo, Dunia".

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

Referensi - MSDN


10

Fitur keren. Saya hanya ingin menunjukkan penekanan pada mengapa ini lebih baik daripada string.format jika tidak jelas bagi sebagian orang.

Saya membaca seseorang yang mengatakan urutan string.format ke "{0} {1} {2}" untuk mencocokkan parameter. Anda tidak dipaksa untuk memesan "{0} {1} {2}" di string.format, Anda juga dapat melakukan "{2} {0} {1}". Namun, jika Anda memiliki banyak parameter, seperti 20, Anda benar-benar ingin mengurutkan string menjadi "{0} {1} {2} ... {19}". Jika berantakan, Anda akan kesulitan mengatur parameter Anda.

Dengan $, Anda dapat menambahkan parameter sebaris tanpa menghitung parameter Anda. Ini membuat kode lebih mudah dibaca dan dipelihara.

Kelemahan dari $ adalah, Anda tidak dapat mengulangi parameter dalam string dengan mudah, Anda harus mengetiknya. Misalnya, jika Anda bosan mengetik System.Environment.NewLine, Anda dapat melakukan string.format ("... {0} ... {0} ... {0}", System.Environment.NewLine), tetapi, dalam $, Anda harus mengulanginya. Anda tidak dapat melakukan $ "{0}" dan meneruskannya ke string.format karena $ "{0}" mengembalikan "0".

Di samping catatan, saya telah membaca komentar di tpoic duplikat lain. Saya tidak bisa berkomentar, jadi ini dia. Ia mengatakan bahwa

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

membuat lebih dari satu objek string. Ini sebenarnya tidak benar. Jika Anda melakukan ini dalam satu baris, itu hanya membuat satu string dan ditempatkan di cache string.

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

Semuanya mengembalikan string dan hanya membuat satu nilai dalam cache.

Di samping itu:

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

Menciptakan 4 nilai berbeda dalam cache karena ada 4 ";".

Dengan demikian, akan lebih mudah untuk menulis kode seperti berikut ini, tetapi Anda akan membuat lima string yang diinterpolasi saat Carlos Muñoz mengoreksi:

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

Ini menciptakan satu string tunggal dalam cache sementara Anda memiliki kode yang sangat mudah dibaca. Saya tidak yakin tentang kinerjanya, tetapi, saya yakin MS akan mengoptimalkannya jika belum melakukannya.


1
Contoh terakhir Anda salah: Sebenarnya Anda membuat dua string: Satu dari string yang diinterpolasi dan lainnya dari sisa string. Perhatikan bahwa hanya yang dengan {myName} yang diinterpolasi, yang lain tidak berfungsi seperti yang diharapkan.
Carlos Muñoz

1
Dan jika Anda menambahkan $ ke 5 string itu kemudian menciptakan 5 string yang diinterpolasi masing-masing dengan mereka sendiri String.Format()dan kemudian digabungkan pada saat runtime dengan String.Concat. Jadi lebih baik Anda tidak membaginya menjadi beberapa baris
Carlos Muñoz

1
Anda benar @Carlos Muñoz, saya telah memperbaikinya. Terima kasih telah menangkap kesalahannya.
BoBoDev

8

Perhatikan bahwa Anda juga dapat menggabungkan keduanya, yang cukup keren (meskipun terlihat agak aneh):

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

5
Kalau saja Anda bisa memutuskan urutan di mana Anda mengetik $@atau @$. Sayangnya itu hanya bisa$@
Bauss

2
@ Bauss Ini masuk akal. @mendefinisikan bagaimana merepresentasikan string literal. $adalah jalan pintas untuk string.Format. Anggap saja$(@"");
marsze

Ini bukan jalan pintas sebenarnya string.Format. Sangat manis untuk menyajikan nilai yang diuraikan menjadi string.Format, sehingga sebagian masuk akal, tetapi tidak sepenuhnya.
Bauss

3
Saya hanya mengatakan $pada dasarnya adalah panggilan fungsi tersirat sedangkan @merupakan bagian dari literal, seperti mdalam literal desimal. Itu sebabnya hanya ada satu urutan logis.
rawa

2
Saya tahu ini sebagian besar hanya di sini untuk menunjukkan $, tetapi demi kompatibilitas maksimum dan tidak sulit pengkodean apakah pemisah direktori adalah '/' atau '\', dan juga menghindari kekacauan yang tak terhindarkan yang menyebabkan tebasan ganda atau tebas yang hilang di mana harus ada telah menjadi salah satu, saya sarankan menggunakan Path.Combine()daripada menggunakan rangkaian string ketika bekerja dengan direktori dan file.
jrh

6

Ini lebih nyaman daripada string.Format dan Anda bisa menggunakan intellisense di sini juga.

masukkan deskripsi gambar di sini

Dan inilah metode pengujian saya:

[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

Ini menandakan interpolasi string.

Ini akan melindungi Anda karena itu menambah perlindungan waktu kompilasi pada evaluasi string.

Anda tidak akan lagi mendapatkan pengecualian dengan string.Format("{0}{1}",secondParamIsMissing)


6

Contoh berikut menyoroti berbagai keuntungan menggunakan string interpolasi string.Format()sejauh kebersihan dan keterbacaan berjalan. Ini juga menunjukkan bahwa kode di dalam {}dievaluasi seperti argumen fungsi lainnya, sama seperti jika string.Format()kita dipanggil.

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

$ Sintaks bagus, tetapi dengan satu kelemahan.

Jika Anda membutuhkan sesuatu seperti templat string, yang dideklarasikan pada tingkat kelas sebagai bidang ... yah di satu tempat sebagaimana mestinya.

Maka Anda harus mendeklarasikan variabel pada tingkat yang sama ... yang tidak terlalu keren.

Jauh lebih baik menggunakan string. Sintaks untuk hal-hal semacam ini

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);
 }
}

Penggunaan global tidak benar-benar baik dan selain itu - juga tidak bekerja dengan global

 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;
 }
}

Jawaban ini penting karena menunjukkan bahwa interpolasi terjadi ketika Anda "memanggil" $ string, bukan ketika Anda mendeklarasikannya.
dx_over_dt

1
Anda benar tentang anti-pola mendeklarasikan variabel interpolasi Anda di ruang lingkup kelas, namun jika variabel tersebut sudah termasuk sebagai properti kelas, pola ini berfungsi dengan baik.
dx_over_dt

@dx_over_dt Anda salah. String interpolasi dievaluasi pada saat mereka dinyatakan. Itu sebabnya kode sampel tidak masuk akal. Itu juga tidak akan dikompilasi.
NineBerry

@NineBerry Anda benar baik tentang string interpolasi dievaluasi pada saat mereka dinyatakan dan tentang Example_ $ Format tidak mengkompilasi dan tentang kode sampel tidak masuk akal :) Saya telah mengoreksi sampel untuk menjelaskannya dengan lebih baik.
Tom

5

Saya tidak tahu cara kerjanya, tetapi Anda juga dapat menggunakannya untuk menilai nilai Anda!

Contoh:

Console.WriteLine($"I can tab like {"this !", 5}.");

Tentu saja, Anda dapat mengganti "ini!" dengan variabel apa pun atau apa pun yang bermakna, sama seperti Anda juga dapat mengubah tab.



Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.