ฉันไม่เห็นใครแสดงความคิดเห็นในคำถามที่ 2 ที่ชัดเจนของคุณในตอนท้าย: "2: สิ่งนี้น่าสนใจเพียงพอสำหรับฉันที่จะพิจารณาย้ายไปที่ C # หรือไม่ถ้ากรณี VB.NET จำกัด สิ่งที่ฉันสามารถทำได้ด้วยโค้ด"
ฉันชอบแนวทางตัวเลือกมากกว่าที่ C # ให้โปรแกรมเมอร์เลือกว่าจะไม่ จำกัด ตัวเลือกของโปรแกรมเมอร์ ฉันชอบ C # เป็นอย่างมาก แต่สำหรับความไวของตัวพิมพ์เล็กและใหญ่เพียงอย่างเดียวฉันไม่คิดว่ามันจะใกล้เคียงกับการเรียนรู้ภาษาเพียงเพราะเป็นกรณี ๆ ไป คุณสมบัติทั้งหมดมีความสำคัญอย่างไรและเมื่อฉันดูข้อดีของทั้ง C # และ VB.NET ฉันชอบ C # มาก แต่ฉันจะให้มุมมองที่สมดุลอย่างแท้จริงลำเอียงใช่เพราะฉันมีความชอบ แต่ฉันจะซื่อสัตย์เกี่ยวกับข้อเสียของ C # ด้วย
ก่อนอื่นทั้งสองภาษามีข้อดีและข้อเสีย ความแตกต่างที่คุณสามารถทำได้ในภาษาหนึ่งซึ่งไม่สามารถทำได้ในอีกภาษาหนึ่งนั้นลดน้อยลงเนื่องจาก Microsoft กำลังปรับปรุงทั้งสองภาษาและดูเหมือนว่าจะไม่แสดงความลำเอียงที่ไม่เป็นธรรมต่อภาษาใดภาษาหนึ่ง
เมื่อ C # ออกมาครั้งแรก VB ไม่มีความคิดเห็น XML ที่คุณสามารถใส่ไว้ก่อนวิธีการซึ่งฉันชอบใน C # ฉันเกลียดสิ่งนั้นใน VB.NET แต่ฉันเคยเห็นในช่วงหลายปีที่ผ่านมาว่ามีการเพิ่มคุณลักษณะหลายอย่างที่ไม่ได้อยู่ในภาษาเดียวลงในอีกภาษาหนึ่ง (ทีมนักพัฒนา MS เดียวกันพัฒนาทั้ง C # และ VB ดังนั้นจึงสมเหตุสมผลที่คุณสมบัติควรจะคล้ายกันมาก)
แต่คุณถามว่า C # มีอะไรบ้างที่ VB ไม่มี นี่คือบางส่วนที่ฉันคิดได้ทันที:
1: C # กระชับกว่าและพิมพ์น้อยลง .. ในหลาย ๆ วิธี! ฉันเคยเห็นความโง่เขลาพูดเมื่อมีการอ้างสิทธิ์ในทางตรงกันข้าม VB บันทึกการพิมพ์ แต่โปรดฟังคนที่บอกคุณว่าพวกเขาใช้ทั้งสองภาษาและไม่ค่อยมีใครใช้ ฉันใช้ทั้ง C #และVB, C # ที่บ้านเพราะฉันชอบ (และเมื่อฉันทำงานกับ C # ในที่ทำงาน) และคำของานล่าสุดของฉันที่ฉันใช้ VB ไม่ใช่ C # ดังนั้นฉันจึงใช้ VB บ่อยขึ้นในตอนนี้ (เป็นเวลาประมาณ 10 เดือนแล้ว) แต่จากคำให้การส่วนตัวของฉันฉันชอบ C # มากและในแง่ของการพิมพ์จริง VB นั้นพิมพ์ได้มากกว่ามาก ตัวอย่างหนึ่งที่ฉันเคยอ่านที่มีคนพยายามพูดว่า VB มีความกระชับมากขึ้นคือการให้ตัวอย่าง 'with ... ' ที่มีตัวแปรยาวร่วมด้วยดังนั้นใน VB คุณสามารถใช้ ".property" ได้ นี่คือความโง่เขลาในการอ้างว่า VB ต้องการการพิมพ์น้อยลง มีบางสิ่ง (ไม่ใช่แค่ตัวอย่างนี้) ที่ VB สั้นลง แต่หลาย ๆ ครั้งเมื่อ C # กระชับขึ้นในทางปฏิบัติจริง
แต่เหตุผลที่สำคัญที่สุดที่ฉันเชื่อว่า C # มีความรัดกุมกว่าคือคำสั่ง "IF / THEN" ของ VB ถ้าคำสั่งเป็นเรื่องธรรมดา ใน C # ไม่มีคำว่า 'แล้ว' ให้พิมพ์! :) นอกจากนี้คำสั่ง 'end ... ' ทั้งหมดจะพิมพ์ซึ่งใน c # โดยปกติจะเป็นเพียงวงเล็บปีกกาปิดเดียว '}' ฉันได้อ่านมาว่าบางคนอ้างว่าคำฟุ่มเฟือยมากกว่านี้ใน VB.NET เป็นข้อได้เปรียบของ VB เนื่องจากคำสั่ง / สัญลักษณ์การปิดกั้นหลายรายการสามารถซ้อนกันและจบลงทันทีข้างๆกัน แต่ฉันค่อนข้างไม่เห็นด้วย คน ๆ หนึ่งมักจะเขียนโปรแกรมได้ดีกว่าทั้งใน C # หรือ VB มากกว่าโปรแกรมเมอร์คนอื่นเพราะการแก้ไขโค้ดครั้งต่อไปสามารถออกแบบได้ดีกว่า สิ่งนี้ใช้กับ 'วงเล็บปีกกาปิดจำนวนมากที่สับสนใน C #' บวกหากบล็อกที่ซ้อนกันทั้งหมดเป็นประเภทเดียวกันเช่น IF ที่ซ้อนกันหลายตัว VB จะประสบปัญหาเดียวกันกับที่มีใน C # นี่ไม่ใช่ข้อได้เปรียบใน VB สถานการณ์นี้เป็นเหตุผลว่าทำไมฉันจึงชอบแสดงความคิดเห็นว่าสัญลักษณ์ปิดหรือคำสั่งปิดของฉันใช้กับทั้งสองภาษาอย่างไร ใช่นี่เป็นเรื่องละเอียดกว่าที่ต้องทำ แต่ในภาษาใดภาษาหนึ่งคุณมีตัวเลือกที่จะชัดเจนซึ่งเป็นสิ่งสำคัญในการตัดสินตามสถานการณ์เฉพาะกรณี ฉันคิดว่าความชัดเจนของโค้ดนั้นสำคัญมาก
2: VB ไม่มีความคิดเห็นแบบหลายบรรทัด เมื่อฉันทำงานกับ VB ฉันไม่รังเกียจ จากนั้นฉันก็ไปเรียนภาษา C สองสามภาษา ตอนนี้ฉันกลับมาใช้ VB.NET เป็นส่วนใหญ่ในที่ทำงานและฉันคิดถึงพวกเขา มันเป็นเพียงสิ่งที่คุณสะดวกและต้องเสียไป :(
3: 'andalso' และ 'orelse' ของ VB ค่อนข้างน่ารำคาญในการพิมพ์ทั้งหมดนั้นเมื่ออยู่ใน C # มันเป็นเพียง '&&' และ '||' อีกครั้งพิมพ์น้อยลง นี่ไม่ใช่เรื่องยากในรหัสของฉันทั้งใน VB และ C # หากมีสิ่งใดสำหรับฟังก์ชันการทำงาน 'หรือ' กับ 'OrElse' มักจะไม่สำคัญยกเว้น 'OrElse' จะเร็วกว่าสำหรับคอมพิวเตอร์ดังนั้นหากโปรแกรมเมอร์ใช้ 'หรือ' และ 'และ' ใน VB ก็จะสร้างรหัสที่เหมาะสมน้อยกว่าสำหรับ คนที่ชอบความชัดเจนของรหัส "หรือ" นั้นง่ายกว่าการอ่าน "OrElse" มาก
4: มีความยืดหยุ่นมากขึ้นในการวางโค้ดใน C # เมื่อบรรทัดยาวและคุณต้องการรวมไว้ในบรรทัดถัดไปฉันเกลียดการปรับรหัสของฉัน 'การควบคุม' ของ VB.NET C # ทำเพียงเล็กน้อย แต่ฉันพบว่ามีประโยชน์มากกว่าใน C # โดยที่ใน VB จะควบคุมได้มากกว่า แต่นี่เป็น VB.NET IDE เทียบกับ C # IDE มากกว่าภาษาตัวเอง แต่ฉันไม่รู้ว่าคุณต้องการคุณสมบัติภาษาทั้งสองอย่างหรือล้วนๆโดยไม่มีความแตกต่างของ IDE
5: สิ่งหนึ่งที่ฉันพลาดจริงๆคือแค่สร้างบล็อกโค้ดใหม่ใน C # ฉันอาจมีหลายอย่างเกิดขึ้นในวิธีการและฉันต้องการประกาศตัวแปรในบล็อกโค้ดที่เล็กมาก แต่ไม่มีตัวแปรนั้นที่ประกาศนอกบล็อกนั้นใน วิธีการทั้งหมด ใน C # เราสามารถสร้างบล็อกใหม่โดยใช้ "{" และลงท้ายด้วย "}" VB ไม่มีคุณสมบัติดังกล่าว แต่การจับคู่ที่ใกล้เคียงที่สุดคือบล็อก 'If True Then' และ 'End If' ที่ไม่มีเงื่อนไข (สังเกตอักขระ 2 ตัว C # เทียบกับ 18 อักขระ VB.NET เทียบเท่าอีกครั้ง ... พิมพ์เพิ่มเติมใน VB)
6: ตัวดำเนินการเพิ่มและลดตัวเอง: ++ และ - เช่นเดียวกับmyVariable++
หรือ++myVariable
หรือเวอร์ชันลดที่เทียบเท่า สิ่งนี้มีประโยชน์มาก ... นี่คือตัวอย่างของรหัสจริงเมื่อฉันพลาด C # อย่างมาก:
// C#:
while (txt.Length > x)
{
thisChar = txt[x];
if (charsAllowedWithoutLimit.Contains(thisChar)) { ++x; }
else if (allowLettersWithoutLimit && char.IsLetter(thisChar)) { ++x; }
else if ((x2 = charsAllowedWithLimit.IndexOf(thisChar)) >= 0)
{
++x; if (++usedCountA[x2] > charAllowedLimit[x2]) { break; }
}
else { break; }
}
' VB.NET:
While (txt.Length > x)
thisChar = txt(x)
If (charsAllowedWithoutLimit.Contains(thisChar)) Then
x += 1
ElseIf (allowLettersWithoutLimit AndAlso Char.IsLetter(thisChar)) Then
x += 1
Else
x2 = charsAllowedWithLimit.IndexOf(thisChar)
If (x2 >= 0) Then
x += 1
usedCountA(x2) += 1S
If usedCountA(x2) > charAllowedLimit(x2) Then Exit While
Else
Exit While
End If
End If
End While
และเพื่อให้เป็นตัวอย่างที่ดีมากสำหรับกฎ C # นี่คือรหัสเพิ่มเติมที่ฉันเขียนเป็นการส่วนตัวเมื่อเร็ว ๆ นี้:
// C#
public static bool IsNotWithin(this Byte v, Byte v1, Byte v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this SByte v, SByte v1, SByte v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this Int16 v, Int16 v1, Int16 v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this Int32 v, Int32 v1, Int32 v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this Int64 v, Int64 v1, Int64 v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this UInt16 v, UInt16 v1, UInt16 v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this UInt32 v, UInt32 v1, UInt32 v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this UInt64 v, UInt64 v1, UInt64 v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this Decimal v, Decimal v1, Decimal v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsWithin(this Byte v, Byte v1, Byte v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this SByte v, SByte v1, SByte v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this Int16 v, Int16 v1, Int16 v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this Int32 v, Int32 v1, Int32 v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this Int64 v, Int64 v1, Int64 v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this UInt16 v, UInt16 v1, UInt16 v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this UInt32 v, UInt32 v1, UInt32 v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this UInt64 v, UInt64 v1, UInt64 v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this Decimal v, Decimal v1, Decimal v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
' And the VB equivalent is a mess! Here goes:
<Extension()>
Public Function IsNotWithin(v As Byte, value1 As Byte, value2 As Byte) As Boolean
Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function
<Extension()>
Public Function IsNotWithin(v As SByte, value1 As SByte, value2 As SByte) As Boolean
Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function
<Extension()>
Public Function IsNotWithin(v As Int16, value1 As Int16, value2 As Int16) As Boolean
Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function
' the % suffix means 'As Integer' in VB.
<Extension()>
Public Function IsNotWithin(v%, value1%, value2%) As Boolean
Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function
' the & suffix means 'As Long' in VB.
<Extension()>
Public Function IsNotWithin(v&, value1&, value2&) As Boolean
Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function
<Extension()>
Public Function IsNotWithin(v As UInt16, value1 As UInt16, value2 As UInt16) As Boolean
Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function
<Extension()>
Public Function IsNotWithin(v As UInt32, value1 As UInt32, value2 As UInt32) As Boolean
Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function
<Extension()>
Public Function IsNotWithin(v As UInt64, value1 As UInt64, value2 As UInt64) As Boolean
Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function
' the @ suffix means 'As Decimal' in VB.
<Extension()>
Public Function IsNotWithin(v@, value1@, value2@) As Boolean
Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function
<Extension()>
Public Function IsWithin(v As Byte, value1 As Byte, value2 As Byte) As Boolean
Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function
<Extension()>
Public Function IsWithin(v As SByte, value1 As SByte, value2 As SByte) As Boolean
Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function
<Extension()>
Public Function IsWithin(v As Int16, value1 As Int16, value2 As Int16) As Boolean
Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function
' the % suffix means 'As Integer' in VB.
<Extension()>
Public Function IsWithin(v%, value1%, value2%) As Boolean
Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function
' the & suffix means 'As Long' in VB.
<Extension()>
Public Function IsWithin(v&, value1&, value2&) As Boolean
Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function
<Extension()>
Public Function IsWithin(v As UInt16, value1 As UInt16, value2 As UInt16) As Boolean
Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function
<Extension()>
Public Function IsWithin(v As UInt32, value1 As UInt32, value2 As UInt32) As Boolean
Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function
<Extension()>
Public Function IsWithin(v As UInt64, value1 As UInt64, value2 As UInt64) As Boolean
Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function
' the @ suffix means 'As Decimal' in VB.
<Extension()>
Public Function IsWithin(v@, value1@, value2@) As Boolean
Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function
บางทีนี่อาจเป็นหลักฐานว่า C # มีความรัดกุมมากขึ้น แต่ไม่ใช่โปรแกรมเมอร์ทุกคนที่ชอบความกระชับ บางคนชอบอ่าน "if a <b then ... " เพราะมันเป็นธรรมชาติของภาษามนุษย์มากกว่า และไม่เป็นไร การตั้งค่าเป็นเรื่องปกติ สำหรับฉันความพยายามด้วยมือเป็นปัจจัยที่ฉันให้ความสำคัญและฉันคิดว่าใคร ๆ ก็เคยชินกับการคิดในสัญลักษณ์ใด ๆ ที่พวกเขาต้องการสำหรับ "if" และ "then" เป็นสัญลักษณ์ของตัวอักษรและ C # ของคำสั่ง "if (เงื่อนไข);" ไวยากรณ์เป็นสัญลักษณ์ด้วย อันหนึ่งใกล้เคียงกับไวยากรณ์ของผู้ที่ไม่ใช่โปรแกรมเมอร์มากกว่าอีกอัน ฉันชอบแบบรวบรัด
ฉันยังคิดว่าจำเป็นต้องใช้ 'c' หลังตัวอักษรใน VB เพื่อให้เป็นตัวอักษรตามตัวอักษรแทนที่จะเป็นสตริงนั้นน่ารำคาญ ฉันชอบความกระชับของ C # กับสิ่งนั้นมาก เมื่อเมธอดต้องการอักขระลิเทอรัลคุณต้องระบุอักขระที่ไม่ใช่สตริงที่มีความยาวอักขระเดียวดังนั้นบางครั้งคุณถูกบังคับให้ใช้":"c
ใน VB ในขณะที่ C # คือ':'
มันเป็น ฉันคิดว่านี่เป็นการเลือกที่ดี
เพื่อความเป็นธรรมฉันจะบอกว่ามีข้อดีที่ผมชอบที่จะ VB เช่นไม่ต้องใส่วงเล็บว่างเปล่าหลังจากเรียกวิธีการเช่นDim nameUpper$ = name.ToUpperInvariant
ที่ C # string nameUpper = name.ToUpperInvariant()
ต้องวงเล็บที่ว่างเปล่า หรือสองเท่าเช่นการตัดแต่งมันมากเกินไป: VSDim nameUpper$ = name.Trim.ToUpperInvariant
string nameUpper = name.Trim().ToUpperInvariant()
ฉันชอบการใช้งานที่กระชับของ VB ว่าฉันใช้อย่างไร$
ด้านบนเพื่อหรี่แสง 'As String' โดยที่ C # ไม่มีทางลัดเหล่านั้น VB มีทางลัดสำหรับประเภท String, Integer, Long, Decimal, Single และ Double แต่ข้อเสียคือมันไม่ค่อยชัดเจนดังนั้นฉันจึงใช้ด้วยความระมัดระวัง แต่อย่างไรก็ตามฉันชอบรหัสที่กระชับมากกว่า
นั่นเป็นเพียงคำพูดบางส่วนจากโปรแกรมเมอร์ผู้ช่ำชองและตามที่ฉันพิจารณานี่คือคำให้การในการเขียนโปรแกรมของฉันเกี่ยวกับ C # vs VB ทั้งสองภาษาเป็นภาษาที่ดีในความคิดของฉัน แต่ใช่ฉันยังชอบ C # มาก
ps เนื่องจากฉันวางแผนที่จะเขียนโปรแกรมมาเกือบตลอดชีวิตฉันจึงได้เรียนรู้การพิมพ์ใหม่โดยใช้แป้นพิมพ์ที่มีประสิทธิภาพสูงสุดนั่นคือแป้นพิมพ์ Dvorak ซึ่งใช้ความพยายามในการพิมพ์ภาษาอังกฤษประมาณ 1/3 มากกว่าแป้นพิมพ์ Qwerty ค้นดูสิ. บางทีคุณอาจต้องการเปลี่ยนด้วย ;) มันทำให้การพิมพ์ของฉันง่ายขึ้น 67%! :) ฉันสนับสนุนให้ทุกคนคิดนอกกรอบและประเมินประสิทธิภาพที่ดีขึ้นในงานของคุณ Dvorak Simplified Keyboard Layout และ C # ได้ทำสิ่งนี้ให้ฉันแล้ว :)
PSS ฉันจะเปรียบเทียบ Dvorak และ C # กับเมตริกซึ่งต่างจากรูปแบบแป้นพิมพ์ Qwerty และ VB กับการวัดเชิงประจักษ์ Dvorak, เมตริกและ C # นั้น 'สะอาด' แต่ VB อยู่ไม่ไกลจริงๆ แต่ต้องทนทุกข์ทรมานจากความจำเป็นที่จะต้องเข้ากันได้กับรหัส VB6 เก่าและรหัสก่อน. NET เช่น 'หรือ' เทียบกับ 'OrElse' และ 'IIF ()'
ฉันจบด้วยความระมัดระวัง โปรดใช้ความระมัดระวังมากขึ้นในการรับฟังคนที่ไม่รู้จริงๆว่าพวกเขากำลังพูดถึงอะไร ครึ่งหนึ่งของข้อเสียทั้งหมดต่อทั้ง VB และ C # คือไม่ใช่ปัญหาใด ๆ อีกต่อไปและผู้คนยังคงโพสต์เกี่ยวกับพวกเขาโดยไม่รู้ถึงข้อเสียที่ยังคงมีอยู่ในภาษา ตัวอย่างที่ดีที่สุดที่ฉันคิดได้คือความคิดเห็น XML สำหรับวิธีการที่ใช้เครื่องหมายวรรคตอนสามใน VB หรือสัญลักษณ์ความคิดเห็นสแลชสามตัวใน C # แต่โปรดสังเกตตัวเองว่าคน ๆ นั้นพูดจากความไม่รู้หรือจากประสบการณ์ ประจักษ์พยานส่วนตัวหมายถึงพวกเขารู้จากประสบการณ์จริง และหลังจากที่ใครบางคนมีประสบการณ์มากมายในนั้นแล้วก็จงหูผึ่ง ฉันมีประสบการณ์มากกว่า 10 ปีทั้งใน C # และ VB และมันก็เดือดพล่าน: ทั้งคู่เป็นภาษาที่ดี (มาก) และความแตกต่างส่วนใหญ่คุณจะเห็นได้ทันทีภายใน 5 นาทีหลังจากอ่านโค้ด แต่ใช่คุณสมบัติอื่น ๆ อาจใช้เวลาหลายปีในการหาแต้มต่อ และหนึ่งแต้มต่อที่ฉันรู้ (ใน C #) ฉันทำได้ ' แม้จะคิดถึงสถานการณ์ในชีวิตจริงที่จะเป็นประโยชน์ ดังนั้นบางทีมันอาจไม่ใช่แต้มต่อ
ขอให้สนุกกับการเขียนโค้ด!