เมื่อใดที่“ ลอง” ควรจะใช้ในชื่อเมธอด C #


180

เรากำลังพูดคุยกับเพื่อนร่วมงานของเราเกี่ยวกับความหมายว่าถ้าชื่อวิธีการขึ้นต้นด้วย "ลอง"

มีความคิดเห็นดังต่อไปนี้:

  • ใช้ "ลอง" เมื่อวิธีสามารถคืนค่าเป็นศูนย์ได้
  • ใช้ "ลอง" เมื่อวิธีการจะไม่เกิดข้อยกเว้น

คำจำกัดความอย่างเป็นทางการคืออะไร "ลอง" พูดในชื่อวิธีการอะไร? มีแนวทางที่เป็นทางการเกี่ยวกับเรื่องนี้หรือไม่?


83
+1 คนที่คิดมากเรื่องนี้ในชื่อฟังก์ชั่นของพวกเขาจริงๆแล้วมองหา "คนต่อไป" ไม่แน่ใจว่าทำไมนี่ถึงได้รับการโหวตอย่างใกล้ชิด (และมาจากผู้ชายที่หล่อมากในคืนนี้)
Jonathon Reinhart

7
@ JonathonReinhart มันได้คะแนนอย่างใกล้ชิดเพราะ"ในขณะนี้อยู่คำถามนี้ไม่เหมาะสำหรับรูปแบบคำถาม & คำตอบของเราเราคาดว่าคำตอบจะได้รับการสนับสนุนโดยข้อเท็จจริงการอ้างอิงหรือความเชี่ยวชาญเฉพาะ โพลหรือการอภิปรายเพิ่มเติม "
Pranav Hosangadi

16
มีเป็นแถลงการณ์อย่างเป็นทางการโดยไมโครซอฟท์ที่ตอบคำถาม (ดูคำตอบของฉัน) นั่นไม่ใช่ความจริงเหรอ?
Erik Schierboom

6
@PranavHosangadi ตามที่ Erik ได้กล่าวไว้นั้นได้รับการสนับสนุนโดยข้อเท็จจริง นอกจากนี้ยังมีนักพัฒนา C # ที่มีประสบการณ์มากมายที่นี่ซึ่งมีความเชี่ยวชาญเฉพาะด้านเพื่อให้คำตอบที่ถูกต้อง Hell, Eric Lippert เป็นหัวหน้าสถาปนิกภาษา C # ฉันคิดว่าคุณสามารถเรียกความเชี่ยวชาญเฉพาะนั้นได้
Jonathon Reinhart

4
@ErikSchierboom นั่นคือแนวทางของ MS คือความจริง คำแนะนำของ MS เป็นแนวทางที่ถูกต้องในการใช้นั้นเป็นเชิงอัตวิสัยและเป็นที่ถกเถียงกัน
Servy

คำตอบ:


148

สิ่งนี้เรียกว่ารูปแบบTryParseและได้รับการรับรองโดย Microsoft หน้าข้อยกเว้นอย่างเป็นทางการและประสิทธิภาพของ MSDN ระบุว่า :

พิจารณารูปแบบ TryParse สำหรับสมาชิกที่อาจเกิดข้อยกเว้นในสถานการณ์ทั่วไปเพื่อหลีกเลี่ยงปัญหาด้านประสิทธิภาพที่เกี่ยวข้องกับข้อยกเว้น

ดังนั้นหากคุณมีรหัสซึ่งกรณีการใช้งานปกติอาจหมายความว่ามันอาจจะมีข้อยกเว้น (เช่นการแยกวิเคราะห์ int) รูปแบบTryParse มีเหตุผล


2
ลิงก์อื่นที่มีประโยชน์ซึ่งบันทึกรูปแบบนี้ (ค้นหา TryParse) blogs.msdn.com/b/kcwalina/archive/2005/03/16/396787.aspx
Vivek Maharajh

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

5
+1 เพียงเพิ่มคำสั่งนี้โดยทั่วไปจะมีข้อยกเว้นสำหรับสถานการณ์ "พิเศษ" หากคุณกำลังทำบางสิ่งที่อาจล้มเหลวได้ง่ายและความล้มเหลวนั้นไม่โดดเด่นเป็นพิเศษการใช้รูปแบบนี้จะมีความหมายมากกว่าการลอง / จับ
อดัมโรบินสัน

รูปแบบดังกล่าวต้องการแนวทางจาก Microsoft จริง ๆ หรือไม่ ดูเหมือนสิ่งพื้นฐานค่อนข้าง
Dave Lawrence

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

119

(แก้ไขแล้ว)มีแนวทางอย่างเป็นทางการตามที่ Erik แนะนำ

เมื่อฉันเห็นTrySomethingวิธีฉันถือว่ามัน

  • ไม่โยน
  • ผลตอบแทน bool
  • ถ้าฉันคาดหวังค่ามันจะถูกส่งกลับผ่านพารามิเตอร์ 'ออก'
  • มีSomethingวิธีการอยู่ที่อนุญาตให้ฉันจัดการกับข้อยกเว้นใด ๆ ด้วยตัวเอง (แก้ไขแนะนำโดย Jesse Webb)

4
การแก้ไข - มันมีแนวทางอย่างเป็นทางการ ดูคำตอบของ Erik
nothrow

8
+1 แต่ฉันก็มีความคาดหวังที่ 4: หากมีTryFooวิธีจะมีFooวิธีที่คล้ายกันซึ่งช่วยให้ฉันจัดการข้อยกเว้น `` ตัวเอง ' ลายเซ็นของวิธีการเหล่านี้อาจแตกต่างกันดังนั้นการใช้งานของพวกเขาจะไม่สามารถแลกเปลี่ยนกันได้หากไม่มีการเปลี่ยนแปลงรหัสอื่น ๆ
Jesse Webb

1
@JesseWebb ขอบคุณที่ชี้ให้เห็น ฉันได้เพิ่มความคิดเห็นของคุณลงในคำตอบของฉันถ้าคุณไม่รังเกียจ
nothrow

1
"ไม่โยน" ดูเหมือนว่าให้ฉันมากไปกว่าปกติ ตัวอย่างเช่น Int32.TryParse (สตริง, NumberStyles, IFormatProvider, Int32) จะส่งอาร์กิวเมนต์ ArgumentException หากไม่ชอบพารามิเตอร์สไตล์
Jirka Hanika

ฉันยอมรับว่า "ไม่ทิ้ง" อาจถือได้ว่าเป็นสิ่งที่มากเกินไป แต่ฉันเชื่อว่าเจตนาที่จะสื่อว่ามันไม่ได้เป็นผลมาจากการดำเนินการแทนที่จะเป็นผลมาจากมูลค่าของพารามิเตอร์
สับสน

8

ฉันคิดว่าคุณควรใช้tryเมื่อคุณต้องการดำเนินการต่อ มันไม่สำคัญว่าเมธอดจะส่งคืนค่าบางค่าหรือไม่

กรณีที่ 1: หากผลตอบแทนดีคุณสามารถดำเนินการต่อในทางใดทางหนึ่ง

กรณีที่ 2: หากยังไม่ส่งคืน: ยังคงใช้ได้ คุณสามารถดำเนินการในวิธีอื่น

และถ้าคุณคาดหวังว่าค่าบางอย่างเป็นผลลัพธ์ของวิธีการนั้นให้ใช้outพารามิเตอร์

ตัวอย่าง

int value
if (dictionary.TryGetValue("key", out value))
{
    // Proceed in some way
}
else
{
    // Proceed in some other way
}

6

คุณต้องใช้ "ลอง" ในชื่อเมธอดเมื่อคุณต้องการแสดงให้เห็นถึงความจริงที่ว่าการเรียกใช้เมธอดสามารถสร้างผลลัพธ์ที่ไม่ถูกต้อง การทำตามมาตรฐาน. NET นั้นไม่ใช่ฟังก์ชั่นที่ทำให้เกิดข้อยกเว้น แต่ฟังก์ชั่นที่คืนค่าบางค่าVALIDหรือNON_VALIDจากมุมมองของโปรแกรมมีค่า

ในตอนท้ายข้อตกลงทั้งหมดนี้เกี่ยวกับการตั้งชื่อที่คุณตัดสินใจใช้ในกลุ่มของคุณ


5

ตรวจสอบให้แน่ใจว่าได้รวมtryไว้ใน methodname ของคุณหาก:

  • คุณไม่ได้โยนข้อยกเว้นใด ๆ
  • วิธีการของคุณมีลายเซ็นต่อไปนี้: bool TrySomething(input, out yourReturn)

ดังนั้นโดยทั่วไปถ้าเราใช้ - tryวิธีเราจะได้รับผลบูลีนกลับมา

ดังนั้นรหัสต่อไปนี้จะไม่ส่งข้อยกเว้นใด ๆ :

string input = "blabla";
int number;
if (int.TryParse(input, out number))
{
// wooohooo we got an int!
} else
{
//dooh!
}

ในขณะที่รหัสนี้สามารถ (และในกรณีนี้) โยนข้อยกเว้น:

string input = "blabla";
int number;
try
{
     number = int.Parse(input); //throws an exception
}
catch (Exception)
{
     //dooh!
}

การใช้วิธีการทดลองเป็นวิธีที่ปลอดภัยและป้องกันรหัส นอกจากนี้ข้อมูลโค้ด # 2 ยังใช้ประสิทธิภาพในการดำเนินการมากขึ้นหากไม่ใช่จำนวนเต็ม


คุณควรอ่านข้อมูลโค้ด # 2 int number = int.Parse(input);หากคุณต้องการให้มีความหมายมากกว่าในบริบทนี้
Pierre Arnaud

@PierreArnaud ขอบคุณเปลี่ยน!
Fabian Bigler

คุณยังคงไม่มีการint number;ประกาศก่อนที่จะลองบล็อกและการnumber = ...มอบหมาย
Pierre Arnaud

@PierreArnaud ขอบคุณฉันยังรวม 'int number' ตอนนี้
เฟเบียนบิ๊กเลอร์

โปรดทราบว่าคุณยังคงสามารถโยนข้อยกเว้นได้หากข้อยกเว้นนั้นไม่เกี่ยวข้องกับการดำเนินการโดยตรงเช่นTryLoadFile(path, out file)woah จาก RAM ดังนั้นผู้โทรจึงคาดหวังว่าจะไม่มีข้อผิดพลาดสำหรับเส้นทางที่ไม่ถูกต้องหรือการเข้าถึงถูกปฏิเสธ แต่เป็นข้อยกเว้นสำหรับสิ่งที่แปลกประหลาดที่อาจผิดพลาดได้ และบันทึกเอกสารไว้
Luke Puplett

0

ลุงบ๊อบให้ตัวอย่างด้านล่างนี้ในหนังสือของเขารหัสสะอาด เมื่อใดก็ตามที่เราคาดว่าจะมีข้อผิดพลาดเกิดขึ้นเราสามารถใช้Tryคำนำหน้ากับชื่อเมธอด:

public void sendShutDown()
{
    try{
        tryToShutDown();
    } catch (DeviceShutDownError e) {
        logger.log(e);            
    }
}

และจากนั้น (ดัดแปลง):

private void tryToShutDown()
{
    //some code with no error handling, but
    //something might go wrong here
}

tryToShutDownวิธีการไม่ได้ทำให้จัดการข้อผิดพลาดใด ๆ เนื่องจากว่าเป็นความรับผิดชอบของsendShutDownวิธีการ

TryParseรูปแบบของไมโครซอฟท์ละเมิดแนวทางรหัสสะอาดที่บอกว่าเราควรหลีกเลี่ยงพารามิเตอร์ที่ส่งออก

หากเราไม่ได้พัฒนา C # เวอร์ชันใหม่เราไม่จำเป็นต้องปฏิบัติตามแนวทางทั้งหมดของ Microsoft บางครั้งพวกเขาก็ไม่ได้ดีที่สุด

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