ในระบบของฉันฉันมักทำงานกับรหัสสนามบิน ( "YYZ"
, "LAX"
, "SFO"
ฯลฯ ) พวกเขามักจะอยู่ในรูปแบบเดียวกันแน่นอน (3 ตัวอักษรแสดงเป็นตัวพิมพ์ใหญ่) โดยทั่วไประบบจะจัดการกับ 25-50 ของรหัส (ต่างกัน) ต่อคำขอ API ด้วยการจัดสรรรวมกว่าพันรายการระบบจะส่งผ่านแอปพลิเคชันของเราหลายเลเยอร์และเปรียบเทียบกับความเท่าเทียมกันบ่อยครั้ง
เราเริ่มต้นด้วยการส่งสายไปรอบ ๆ ซึ่งใช้งานได้ดี แต่เราก็สังเกตเห็นข้อผิดพลาดในการเขียนโปรแกรมจำนวนมากได้อย่างรวดเร็วโดยการส่งรหัสผิดไปที่ไหนสักแห่งคาดว่ารหัส 3 หลัก นอกจากนี้เรายังพบปัญหาที่เราควรทำการเปรียบเทียบแบบตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ แต่ไม่ได้ทำให้เกิดข้อบกพร่อง
จากนี้ฉันตัดสินใจที่จะหยุดการส่งผ่านสายไปรอบ ๆ และสร้างAirport
ชั้นเรียนซึ่งมีตัวสร้างเดียวที่ใช้และตรวจสอบรหัสสนามบิน
public sealed class Airport
{
public Airport(string code)
{
if (code == null)
{
throw new ArgumentNullException(nameof(code));
}
if (code.Length != 3 || !char.IsLetter(code[0])
|| !char.IsLetter(code[1]) || !char.IsLetter(code[2]))
{
throw new ArgumentException(
"Must be a 3 letter airport code.",
nameof(code));
}
Code = code.ToUpperInvariant();
}
public string Code { get; }
public override string ToString()
{
return Code;
}
private bool Equals(Airport other)
{
return string.Equals(Code, other.Code);
}
public override bool Equals(object obj)
{
return obj is Airport airport && Equals(airport);
}
public override int GetHashCode()
{
return Code?.GetHashCode() ?? 0;
}
public static bool operator ==(Airport left, Airport right)
{
return Equals(left, right);
}
public static bool operator !=(Airport left, Airport right)
{
return !Equals(left, right);
}
}
สิ่งนี้ทำให้รหัสของเราง่ายต่อการเข้าใจและเราทำให้การตรวจสอบความเท่าเทียมกันของเราง่ายขึ้น, การใช้พจนานุกรม / การตั้งค่า ตอนนี้เรารู้แล้วว่าหากวิธีการของเรายอมรับAirport
อินสแตนซ์ที่มันจะทำงานในแบบที่เราคาดไว้มันก็ทำให้การตรวจสอบวิธีการของเราง่ายขึ้นเป็นการตรวจสอบการอ้างอิงแบบ null
อย่างไรก็ตามสิ่งที่ฉันสังเกตเห็นคือการรวบรวมขยะกำลังทำงานอยู่บ่อยครั้งมากขึ้นซึ่งฉันติดตามไปที่Airport
การรวบรวมจำนวนมาก
วิธีการแก้ปัญหาของฉันไปนี้คือการแปลงเป็นclass
struct
ส่วนใหญ่เป็นเพียงการเปลี่ยนแปลงคำหลักยกเว้นGetHashCode
และToString
:
public override string ToString()
{
return Code ?? string.Empty;
}
public override int GetHashCode()
{
return Code?.GetHashCode() ?? 0;
}
เพื่อจัดการกรณีที่default(Airport)
มีการใช้
คำถามของฉัน:
การสร้าง
Airport
คลาสหรือโครงสร้างเป็นคำตอบที่ดีโดยทั่วไปหรือฉันกำลังแก้ไขปัญหาที่ผิด / แก้ไขด้วยวิธีที่ไม่ถูกต้องด้วยการสร้างประเภทหรือไม่ หากไม่ใช่วิธีที่ดีวิธีแก้ปัญหาที่ดีกว่าคืออะไรแอปพลิเคชันของฉันควรจัดการกับอินสแตนซ์ที่
default(Airport)
ใช้งานอย่างไร ประเภทของdefault(Airport)
แอพพลิเคชั่นของฉันไร้สาระดังนั้นฉันจึงทำif (airport == default(Airport) { throw ... }
ในสถานที่ซึ่งการได้รับอินสแตนซ์ของAirport
(และCode
คุณสมบัติของมัน) มีความสำคัญต่อการดำเนินการ
หมายเหตุ: ฉันได้ตรวจสอบคำถามC # / VB struct - วิธีการหลีกเลี่ยงกรณีที่มีค่าเริ่มต้นเป็นศูนย์ซึ่งถือว่าไม่ถูกต้องสำหรับโครงสร้างที่กำหนด? และใช้ struct หรือไม่ก่อนถามคำถามของฉัน แต่ฉันคิดว่าคำถามของฉันแตกต่างกันพอที่จะรับประกันการโพสต์ของตัวเอง
default(Airport)
ปัญหาได้ก็คือเพียงแค่ไม่อนุญาตให้ใช้อินสแตนซ์เริ่มต้น คุณสามารถทำได้โดยการเขียนคอนสตรัคเตอร์แบบไร้พารามิเตอร์แล้วโยนInvalidOperationException
หรือNotImplementedException
ลงไป