DEV Community

tia for Ookbee

Posted on • Updated on

การดึงค่าจาก Dictionary แบบเช็คค่าแล้วจบในบรรทัดเดียว

วันนี้จะมาพูดถึงการดึงค่าจาก Dictionary ที่ดูเหมือนจะไม่มีอะไร แต่ไม่ค่อยเห็นการใช้ในแบบที่ควรจะเป็นสักเท่าไหร่ครับ

การใช้ ​Dictionary ปกติแล้ว มักจะต้องมีการเช็คก่อนว่ามี key อยู่หรือไม่ เนื่องจากการเรียกจาก key ที่ไม่มีอยู่จะทำให้เกิด exception ดังนั้นจึงมักจะเห็น code แบบนี้เป็นปกติ

  public string FindX_Naive(Dictionary<string, string> dic) 
  {
    if (dic.ContainsKey("X")) return dic["X"];
    else return null;    
  }
Enter fullscreen mode Exit fullscreen mode

แต่บางท่านก็อาจจะเห็นแล้วว่า ปัญหาของ code นี้คือ มันต้องไปวิ่งหา 2 ครั้ง คือ ที่ dic.ContainsKey("X") รอบนึง แล้วก็ที่ dic["X"] อีกรอบนึง แถมยังมี "X" ในโค้ดสองที่อีกต่างหาก

ซึ่งความจริงแล้ว Dictionary ของ .NET มี method TryGetValue() ให้ใช้อยู่แล้ว ซึ่งถ้าเปลี่ยนไปใช้แบบนั้น ก็อาจจะเขียนออกมาได้แบบนี้

  public string FindX_Try(Dictionary<string, string> dic) 
  {
    string s;
    if (dic.TryGetValue("X", out s)) return s;
    else return null;
  }
Enter fullscreen mode Exit fullscreen mode

คราวนี้ เราก็มี "X" ที่เดียว และวิ่งหารอบเดียวแล้วคือตอนที่เรียก TryGetValue แต่ปัญหาคือ code ดูรกรุงรังมาก โดยเฉพาะตัวแปร s ที่ประกาศมาก็ไม่ได้ใช้อะไรมาก แต่โชคดีที่ C# 7 ได้เพิ่มวิธีการประกาศตัวแปร out ให้ทำได้ตรงที่เรียกใช้เลย ดังนั้นเราก็จะสามารถเขียนให้กระชับกว่าเดิมได้

  public string FindX_Try_OutVar(Dictionary<string, string> dic) 
  {
    if (dic.TryGetValue("X", out var s)) return s;
    else return null;
  }
Enter fullscreen mode Exit fullscreen mode

แต่เขียนให้สั้นกว่านี้ก็ยังได้ โดยใช้ conditional operator และ expresion bodied method

  public string FindX_Final(Dictionary<string, string> dic) 
    => dic.TryGetValue("X", out var s) ? s : null;
Enter fullscreen mode Exit fullscreen mode

ซึ่งจะเห็นว่าเขียนสั้นพอ ๆ กับแบบแรก แต่ถูกต้องในแบบที่ควรจะใช้มากกว่า

สรุปคือ ถึงแม้ว่าการเขียนแบบตัวอย่างแรกสุดจะดูเข้าใจง่าย แต่ก็เป็นการสิ้นเปลืองในการที่จะต้องวิ่งหาใน Dictionary สองรอบ ซึ่งก่อนหน้านี้ก็พอมีข้ออ้างได้ว่า code ดูง่ายกว่าเพราะการเขียนแบบใช้ out ก็จะดูเยิ่นเย้อ แต่ตั้งแต่ C# 7 เป็นต้นมา ก็มี feature พอที่จะเขียนรูปแบบดังกล่าวให้อ่านง่ายและได้ประสิทธิภาพดีกว่าแล้วครับ

Top comments (0)