ใน. NET มีประเภทอยู่สองประเภท: การอ้างอิงและค่า (int, double, structs, enums ฯลฯ ) ท่ามกลางความแตกต่างของพวกเขาคือความจริงที่ว่าการอ้างอิงสามารถnull
ในขณะที่ค่าไม่สามารถ ดังนั้นหากคุณมีประเภทค่าและต้องการนำเสนอ "ตัวเลือก" หรือ "ไม่ทราบ" Nullable<>
ความหมายคุณสามารถประดับด้วย โปรดทราบว่าNullable<>
ถูก จำกัด โดยประเภทที่จะยอมรับเฉพาะประเภทค่า (มันมีwhere T : struct
ข้อ) Nullable<>
ยังมีค่าใช้จ่ายพิเศษจากคอมไพเลอร์โดยที่null
ค่าถูกป้องกันจากNullReferenceExceptions
:
string x = null;
x.ToString(); // throws a NullReferenceException
int? y = null;
y.ToString(); // returns ""
ในภาษาการทำงาน (เช่นสกาล่า, F # Haskell, สวิฟท์ ฯลฯ ) มันเป็นเรื่องธรรมดาสำหรับnull
การได้อยู่ นี้เป็นเพราะในคนทั้งมองว่าการดำรงอยู่ของnull
เป็นความคิดที่ดีและนักออกแบบภาษาได้ตัดสินใจที่จะแก้ไขปัญหานี้โดยไม่อนุญาตให้มัน
ซึ่งหมายความว่าเราต้องการวิธีที่จะแสดงค่าที่ไม่ใช่ค่าในภาษาเหล่านี้อีกครั้ง ป้อนOption
ประเภท (ระบบการตั้งชื่อแตกต่างกันไปซึ่งเรียกว่าMaybe
ใน Haskell) นี่เป็นงานที่คล้ายกับNullable
ที่มันล้อมรอบประเภทเพื่อเพิ่มเคสที่ค่าเป็น "None" หรือ "Unknown" เป็นต้น
Option
ความแตกต่างที่แท้จริงอยู่ในฟังก์ชั่นพิเศษให้กับคุณโดยภาษาที่ใช้ เป็นตัวอย่างใช้Option.map
(ใน pseudocode):
function Option<T2> Option.map(opt: Option<T1>, mapFunc: T1 -> T2) {
if (opt is None) return None
else return Option<T2>(mapFunc(opt.Value))
}
ฟังก์ชั่นการผูกมัดOption.map
เป็นวิธีที่มีประสิทธิภาพในการหลีกเลี่ยงการตรวจสอบค่าว่างแบบทั่วไปที่คุณเห็นใน C #:
if (service == null)
return null;
var x = service.GetValue();
if (x == null || x.Property == null)
return null;
return x.Property.Value;
ค่า Nullable ที่เทียบเท่าใน C # จะเป็น:
public static Nullable<T2> Map<T1, T2>(this Nullable<T1> nullable, Func<T1, T2> f)
where T1 : struct
where T2 : struct
{
if (!nullable.HasValue) return (T2?)null;
else return (T2?) f(nullable.Value);
}
อย่างไรก็ตามสิ่งนี้มียูทิลิตี้ที่ จำกัด ใน C # เพราะมันจะใช้ได้เฉพาะกับประเภทของค่า
เวอร์ชั่นใหม่ของ C # นำเสนอตัวดำเนินการ "การขยายพันธุ์แบบ null" ( ?.
) ซึ่งคล้ายกับOption.map
ฟังก์ชันยกเว้นมันจะใช้ได้กับวิธีการและตัวเข้าถึงคุณสมบัติเท่านั้น ตัวอย่างข้างต้นจะถูกเขียนใหม่
return service?.GetValue()?.Property?.Value;