ใน. 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;