มีรูปแบบในคลาส C # เป็นแบบสุดขั้วโดยDictionary.TryGetValue
และint.TryParse
: วิธีการส่งคืนบูลีนที่ระบุความสำเร็จของการดำเนินการและพารามิเตอร์ out ที่มีผลลัพธ์จริง หากการดำเนินการล้มเหลวพารามิเตอร์ out จะถูกตั้งค่าเป็น null
สมมติว่าฉันใช้การอ้างอิงที่ไม่ใช่โมฆะ C # 8 และต้องการเขียนวิธี TryParse สำหรับคลาสของฉันเอง ถูกต้องลายเซ็นคือ:
public static bool TryParse(string s, out MyClass? result);
เนื่องจากผลลัพธ์เป็น null ในกรณีเท็จตัวแปร out ต้องถูกทำเครื่องหมายเป็น nullable
อย่างไรก็ตามโดยทั่วไปจะใช้รูปแบบลองดังนี้:
if (MyClass.TryParse(s, out var result))
{
// use result here
}
เนื่องจากฉันป้อนสาขาเมื่อการดำเนินการสำเร็จผลลัพธ์ไม่ควรเป็นโมฆะในสาขานั้น แต่เนื่องจากฉันทำเครื่องหมายว่าเป็นโมฆะฉันจึงต้องตรวจสอบสิ่งนั้นหรือใช้!
เพื่อแทนที่:
if (MyClass.TryParse(s, out var result))
{
Console.WriteLine("Look: {0}", result.SomeProperty); // compiler warning, could be null
Console.WriteLine("Look: {0}", result!.SomeProperty); // need override
}
มันน่าเกลียดและไม่ประหยัด
เนื่องจากรูปแบบการใช้งานทั่วไปฉันมีตัวเลือกอื่น: โกหกเกี่ยวกับประเภทผลลัพธ์:
public static bool TryParse(string s, out MyClass result) // not nullable
{
// Happy path sets result to non-null and returns true.
// Error path does this:
result = null!; // override compiler complaint
return false;
}
ตอนนี้การใช้งานทั่วไปกลายเป็นดีกว่า:
if (MyClass.TryParse(s, out var result))
{
Console.WriteLine("Look: {0}", result.SomeProperty); // no warning
}
แต่การใช้งานที่ผิดปกติจะไม่ได้รับคำเตือนที่ควรจะ:
else
{
Console.WriteLine("Fail: {0}", result.SomeProperty);
// Yes, result is in scope here. No, it will never be non-null.
// Yes, it will throw. No, the compiler won't warn about it.
}
ตอนนี้ฉันไม่แน่ใจว่าจะไปทางไหน มีคำแนะนำอย่างเป็นทางการจากทีมภาษา C # หรือไม่ มีรหัส CoreFX ใด ๆ ที่แปลงเป็นข้อมูลอ้างอิงที่ไม่สามารถยกเลิกได้ซึ่งแสดงให้ฉันเห็นวิธีการทำเช่นนี้? (ฉันไปหาTryParse
วิธีการIPAddress
เป็นคลาสที่มี แต่ไม่มีการแปลงในสาขาหลักของ corefx)
และรหัสทั่วไปชอบDictionary.TryGetValue
จัดการกับสิ่งนี้อย่างไร (อาจมีMaybeNull
คุณลักษณะพิเศษจากสิ่งที่ฉันพบ) จะเกิดอะไรขึ้นเมื่อฉันสร้างอินสแตนซ์ที่Dictionary
มีค่าประเภทไม่เป็นโมฆะ?
MyClass?
) และทำสวิทช์ในนั้นด้วยcase MyClass myObj:
และ (เป็นcase null:
optionall)