string.format กับตัวแปรเทียบกับตัวแปรอินไลน์


9

ข้อดี / ข้อเสีย (ถ้ามี) คืออะไรที่จะใช้

string output; 
int i = 10;
output = string.Format("the int is {0}", i);

กับ

string output; 
int i = 10;
output = "the int is " + i;

ฉันได้ใช้ตัวอย่างหลังเสมอ แต่ดูเหมือนว่าบทเรียนออนไลน์ส่วนใหญ่จะใช้ตัวอย่าง string.format ฉันไม่คิดว่ามีความแตกต่างที่แท้จริงในแง่ของประสิทธิภาพความคิดเริ่มต้นของฉันคือ coder จึงไม่ต้องแยกสตริงเพื่อแทรกตัวแปร


8
สาเหตุหลักคือทำให้การแปลง่ายขึ้นมากเพราะโปรแกรมของคุณไม่จำเป็นต้องเข้าใจวิธีการสร้างประโยคต่าง ๆ ของภาษา ตัวอย่างเช่นสำนวนและวลีในภาษาฝรั่งเศสมากมายกลับไปด้านหน้าเมื่อเทียบกับการแปลภาษาอังกฤษ
JohnL

คำตอบ:


22

หากคุณคิดว่าการแปลมีความสำคัญในโครงการของคุณไวยากรณ์แรกจะช่วยได้จริงๆ

ตัวอย่างเช่นคุณอาจมี:

static final string output_en = "{0} is {1} years old.";
static final string output_fr = "{0} a {1} ans.";

int age = 10;
string name = "Henri";
System.out.println(string.Format(output_en, name, age));
System.out.println(string.Format(output_fr, name, age));

นอกจากนี้โปรดทราบว่าตัวแปรของคุณอาจไม่อยู่ในตำแหน่งเดียวกันในประโยคที่มีไวยากรณ์นั้น:

static final string output_yoda = "{1} years {0} has.";

4
+1 สำหรับการใช้ Yoda-speak เป็นตัวอย่างของไวยากรณ์ object-subject-verb
Mike Harris

1
ด้วย C # เรามีตัวเลือกใหม่:System.out.println($"{name} is {age} year's old.");
Berin Loritsch


@BerinLoritsch: ซึ่งไม่สามารถใช้งานได้อย่างสมบูรณ์สำหรับการแปลเป็นภาษาท้องถิ่น
ไบรอัน Boettcher

@BryanBoettcher เข้าใจ แต่ฉันไม่เห็นอะไรเลยใน OP ว่าเป็นสิ่งที่พวกเขาพยายามทำสำเร็จ
Berin Loritsch

8

ตรวจสอบคำตอบแรกสำหรับ/programming/4671610/why-use-string-format มันครอบคลุมทุกอย่างในความคิดของฉันว่าทำไมมันถึงดีกว่า

นอกจากนี้แอสเซมบลี. NET แต่ละรายการมีพูลภายในซึ่งมีชุดของสตริงที่ไม่ซ้ำ เมื่อโค้ดของคุณถูกคอมไพล์สตริงตัวอักษรทั้งหมดที่คุณอ้างอิงในรหัสของคุณจะถูกเพิ่มในกลุ่มนี้ หากคุณมีรหัสที่มีลักษณะดังนี้:

"the int is " + i + " and the double is " + d

นั่นทำให้มันมี 2 สายในสระ

ถ้าคุณมี:

"the int is {0} and the double is {1}"

คุณมีสตริงเดียวในพูล

มันค่อนข้างซับซ้อนกว่าที่จะทราบเมื่อ Strings ถูก interned และเมื่อพวกเขาไม่ได้เพราะคอมไพเลอร์มีปัญญาในการตรวจสอบ Strings ที่อาจไม่จำเป็นต้องฝึกงานในบางครั้ง ... ลองดูตัวอย่างบทความนี้ที่ให้รายละเอียดเพิ่มเติมเกี่ยวกับเรื่องนี้ เรื่อง.

แก้ไข: หลังจากที่ขุดขึ้นมาเล็กน้อยฉันได้พบคำตอบที่น่าสนใจสำหรับคำถามเมื่อไรการใช้การเรียงสตริงกับสตริงรูปแบบที่ดีกว่า . ในระยะสั้นผู้เขียนของคำตอบที่มีการโหวต +30 ทำให้ข้อโต้แย้งที่น่าสนใจในความโปรดปรานของการเรียงต่อกันสตริงเมื่อการแปลไม่ได้เกี่ยวข้อง


2
ฉันยังคิดว่าโวหารมันสะท้อนกับผู้คนเช่นคนอย่างฉันที่คุ้นเคยกับ printf และ sprintf จาก c
Jonathan Henson

ฉันอยากรู้ว่าทำไม downvote เพื่อแก้ไขคำตอบของฉัน ขอบคุณ
Jalayn

4

ฉันชอบวิธีแรกเพราะมันช่วยให้ฉันเห็นอย่างถูกต้องว่าสตริงจะมีลักษณะอย่างไรเมื่อส่งออก มันง่ายมากที่จะลืมเพิ่มช่องว่างหรือเพิ่มระยะห่างพิเศษเมื่อต่อท้ายสตริง

ฉันแน่ใจว่ายังมีประโยชน์ในการแสดงด้วยวิธีแรกเนื่องจากไม่ต้องสร้างสายอักขระพิเศษ แต่นั่นไม่ใช่ความกังวลหลักของฉัน


2

ด้วยการใช้ตัวเลือกแรกคุณจะสามารถจัดเก็บสตริงรูปแบบที่ใช้กันทั่วไปและลดความจำเป็นในการพิมพ์และทำให้ง่ายต่อการอัปเดตสตริงในทุกที่ที่ใช้ โดยทั่วไปตัวเลือกแรกจะช่วยให้ DRY สามารถใช้งานได้อย่างง่ายดาย นอกจากนี้ยังเป็นไวยากรณ์ที่ดีกว่าถ้าจำเป็นต้องใช้หลายตัวแปรในสตริงเช่นที่คุณกล่าวถึง


อ้าวฉันเห็นแล้วฉันเดาว่าฉันไม่ได้คิดถึงตัวอย่าง: string.format ("int คือ {0} อีกครั้งก็คือ {0}", int);
Jim

1

ฉันคิดว่าstring.Format()มันง่ายกว่าที่จะเห็นว่าผลลัพธ์จะเป็นอย่างไร (เพื่อให้คุณไม่มีปัญหาเกี่ยวกับช่องว่างที่ถูกลืมหรืออะไรทำนองนั้น) และยังพิมพ์และแก้ไขได้ง่ายขึ้น

หากคุณต้องการทำการจัดรูปแบบที่ง่ายมากการใช้ตัว+ดำเนินการบวกอาจทำได้ง่ายขึ้น แต่ฉันมักจะใช้เฉพาะเมื่อต่อสองสตริงเข้าด้วยกันเท่านั้น

แสดงให้เห็นว่าstring.Format()เป็นเรื่องง่ายที่จะปรับเปลี่ยนพิจารณาว่าคุณต้องการที่จะเพิ่มการหยุดเต็มในตอนท้ายของประโยคในตัวอย่างของคุณ: ไปจากstring.Format("The int is {0}", i)การstring.Format("The int is {0}.", i)เป็นเพียงตัวละครตัวหนึ่ง แต่จาก"the int is " + iไป"the int is " + i + '.'เป็นมากขึ้น

ประโยชน์อีกอย่างหนึ่งก็คือว่ามันช่วยให้คุณสามารถระบุรูปแบบในการใช้งานเช่นstring.Format() string.Format("The int is 0x{0:X}.", i)สิ่งนี้สำคัญยิ่งกว่าเมื่อทำการจัดรูปแบบวันที่

สำหรับประสิทธิภาพstring.Format()นั้นน่าจะช้ากว่าการต่อสตริงอย่างง่าย แต่โค้ดแบบนี้น่าจะไม่ใช่บนเส้นทางที่ร้อนแรงดังนั้นมันจึงไม่สำคัญ StringBuilderและถ้ามันไม่คุณอาจจะดีกว่าด้วยการใช้


string.Format ภายในใช้ StringBuilder ต่อไป
ไบรอัน Boettcher

1

ใช้รหัสที่ทำให้อ่านง่ายที่สุด ไม่ต้องกังวลกับประสิทธิภาพ

สำหรับตัวอย่างด้านล่างของฉันฉันชอบ B เพราะอ่านง่ายกว่า แต่การแปลภาษาข้างต้นก็สมเหตุสมผลเช่นกัน อย่าปล่อยให้ใครบังคับให้คุณใช้สายอักขระจัดรูปแบบแทนที่จะอ่านแล้วชี้ไปที่บล็อกที่ยอดเยี่ยมของ Jeff Atwoods เกี่ยวกับThe โศกนาฏกรรมเศร้าของโรงละคร Micro Optimisations

A:

string output; 
int i = 10;
output = string.Format("the int is {0}", i);

กับ

B:

string output; 
int i = 10;
output = "the int is " + i;

-1

Ref: สตริงเอาต์พุต: รูปแบบหรือ concat ใน C #?

พิจารณารหัสนี้

มันเป็นรหัสของคุณที่ได้รับการแก้ไขเล็กน้อย

  1. ฉันลบ Console.WriteLine เนื่องจากอาจเป็นคำสั่งที่มีขนาดน้อยกว่าสิ่งที่ฉันพยายามวัด
  2. ฉันกำลังดูนาฬิกาจับเวลาก่อนที่จะวนและหยุดทันทีวิธีนี้ฉันจะไม่สูญเสียความแม่นยำถ้าฟังก์ชั่นใช้เช่น 26.4 เห็บเพื่อดำเนินการ
  3. วิธีที่คุณแบ่งผลลัพธ์ตามจำนวนการวนซ้ำนั้นผิด ดูว่ามีอะไรเกิดขึ้นถ้าคุณมี 1,000 มิลลิวินาทีและ 100 มิลลิวินาที ในทั้งสองสถานการณ์คุณจะได้รับ 0 ms หลังจากหารด้วย 1000000
Stopwatch s = new Stopwatch();

var p = new { FirstName = "Bill", LastName = "Gates" };

int n = 1000000;
long fElapsedMilliseconds = 0, fElapsedTicks = 0, cElapsedMilliseconds = 0, cElapsedTicks = 0;

string result;
s.Start();
for (var i = 0; i < n; i++)
    result = (p.FirstName + " " + p.LastName);
s.Stop();
cElapsedMilliseconds = s.ElapsedMilliseconds;
cElapsedTicks = s.ElapsedTicks;
s.Reset();
s.Start();
for (var i = 0; i < n; i++)
    result = string.Format("{0} {1}", p.FirstName, p.LastName);
s.Stop();
fElapsedMilliseconds = s.ElapsedMilliseconds;
fElapsedTicks = s.ElapsedTicks;
s.Reset();


Console.Clear();
Console.WriteLine(n.ToString()+" x result = string.Format(\"{0} {1}\", p.FirstName, p.LastName); took: " + (fElapsedMilliseconds) + "ms - " + (fElapsedTicks) + " ticks");
Console.WriteLine(n.ToString() + " x result = (p.FirstName + \" \" + p.LastName); took: " + (cElapsedMilliseconds) + "ms - " + (cElapsedTicks) + " ticks");
Thread.Sleep(4000);

นี่คือผลลัพธ์ของฉัน:

1000000 x result = string.Format("{0} {1}", p.FirstName, p.LastName); took: 618ms - 2213706 ticks
1000000 x result = (p.FirstName + " " + p.LastName); took: 166ms - 595610 ticks

1
สิ่งนี้จะตอบคำถามได้อย่างไรหากตัวอย่างโค้ดแรกหรือตัวอย่างโค้ดที่สองนั้นมีการออกแบบที่ดีกว่า ครึ่งวินาทีที่ซ้ำกันของการทำซ้ำ 1M จะเป็นอย่างไรหากนี่เป็นรหัสที่ง่ายกว่าสำหรับบุคคลที่จะรักษาหรือไม่

จิมถามว่า "ข้อดีข้อเสียคืออะไร" สิ่งนี้แสดงให้เห็นว่าการทำซ้ำหลายครั้งString.Formatนั้นเร็วกว่า
jp2code

คุณควรพิจารณาเพิ่มคำตอบของคุณอย่างเต็มที่แทนที่จะปล่อยให้มันเป็นบล็อกของรหัสและความแตกต่างจากรหัสของ OP คำตอบของคุณไม่ตอบคำถามของ OP เป็นภาษาอังกฤษ ดูคำตอบอื่น ๆ มันเป็นไปได้ที่จะลบรหัสทั้งหมดออกจากพวกเขาและยังคงมีคำตอบสำหรับคำถามของ OP
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.