ด้วย C # 6.0 ในตัวอย่าง VS2015 เรามีโอเปอเรเตอร์ใหม่?.
ซึ่งสามารถใช้ดังนี้:
public class A {
string PropertyOfA { get; set; }
}
...
var a = new A();
var foo = "bar";
if(a?.PropertyOfA != foo) {
//somecode
}
มันทำอะไรกันแน่?
ด้วย C # 6.0 ในตัวอย่าง VS2015 เรามีโอเปอเรเตอร์ใหม่?.
ซึ่งสามารถใช้ดังนี้:
public class A {
string PropertyOfA { get; set; }
}
...
var a = new A();
var foo = "bar";
if(a?.PropertyOfA != foo) {
//somecode
}
มันทำอะไรกันแน่?
คำตอบ:
มันเป็นโอเปอเรเตอร์ที่มีเงื่อนไข มันหมายถึงโดยทั่วไป:
"ประเมินตัวถูกดำเนินการแรกถ้าเป็นโมฆะให้หยุดด้วยผลลัพธ์เป็นโมฆะมิฉะนั้นประเมินตัวถูกดำเนินการตัวที่สอง (เป็นการเข้าถึงสมาชิกของตัวถูกดำเนินการแรก)"
ในตัวอย่างของคุณประเด็นคือถ้าa
เป็นnull
เช่นนั้นa?.PropertyOfA
จะประเมินnull
แทนที่จะโยนข้อยกเว้น - จากนั้นจะเปรียบเทียบnull
การอ้างอิงนั้นกับfoo
(โดยใช้การ==
โอเวอร์โหลดของสตริง) พบว่าพวกเขาไม่เท่ากันและการดำเนินการจะเข้าสู่เนื้อหาของif
คำสั่ง .
มันก็เป็นแบบนี้:
string bar = (a == null ? null : a.PropertyOfA);
if (bar != foo)
{
...
}
... ยกเว้นว่าa
จะมีการประเมินเพียงครั้งเดียว
โปรดทราบว่าสิ่งนี้สามารถเปลี่ยนประเภทของการแสดงออกได้เช่นกัน FileInfo.Length
ตัวอย่างเช่นพิจารณา นั่นเป็นคุณสมบัติของประเภทlong
แต่ถ้าคุณใช้กับตัวดำเนินการเงื่อนไขแบบ null คุณจะต้องจบลงด้วยนิพจน์ประเภทlong?
:
FileInfo fi = ...; // fi could be null
long? length = fi?.Length; // If fi is null, length will be null
มันจะมีประโยชน์มากเมื่อทำให้ลำดับชั้นและ / หรือวัตถุการทำแผนที่แบนราบ แทน:
if (Model.Model2 == null
|| Model.Model2.Model3 == null
|| Model.Model2.Model3.Model4 == null
|| Model.Model2.Model3.Model4.Name == null)
{
mapped.Name = "N/A"
}
else
{
mapped.Name = Model.Model2.Model3.Model4.Name;
}
มันสามารถเขียนได้เช่น (ตรรกะเดียวกันข้างต้น)
mapped.Name = Model.Model2?.Model3?.Model4?.Name ?? "N/A";
DotNetFiddle.Net ตัวอย่างการทำงาน
( โอเปอเรเตอร์การรวมศูนย์หรือโมฆะแตกต่างจากโอเปอเรเตอร์เงื่อนไขหรือโมฆะ )
นอกจากนี้ยังสามารถใช้งานด้านข้างของผู้ดำเนินการที่ได้รับมอบหมายกับการกระทำ แทน
Action<TValue> myAction = null;
if (myAction != null)
{
myAction(TValue);
}
สามารถลดความซับซ้อนไปที่:
myAction?.Invoke(TValue);
ใช้ระบบ
public class Program
{
public static void Main()
{
Action<string> consoleWrite = null;
consoleWrite?.Invoke("Test 1");
consoleWrite = (s) => Console.WriteLine(s);
consoleWrite?.Invoke("Test 2");
}
}
ผลลัพธ์:
ทดสอบ 2
|| Model.Model2.Model3.Model4.Name == null
จะมีตรรกะเดียวกันมิฉะนั้นในกรณีที่Model.Model2.Model3.Model4.Name
เป็นnull
, mapped.Name
จะอยู่null
Model.Model2.Model3.Model4.Name
null
else
-branch และในขณะที่คุณตัวอย่างที่สองจะไปทดแทนmapped.Name = Model.Model2.Model3.Model4.Name -> mapped.Name = null
mapped.Name = "N/A"
ดูDotNetFiddle ที่แก้ไขแล้ว
สิ่งนี้ค่อนข้างใหม่สำหรับ C # ซึ่งทำให้เราสามารถเรียกใช้ฟังก์ชันที่เกี่ยวข้องกับค่า Null หรือค่า Null ในวิธีการผูกมัด
วิธีเดิมในการบรรลุสิ่งเดียวกันคือ:
var functionCaller = this.member;
if (functionCaller!= null)
functionCaller.someFunction(var someParam);
และตอนนี้มันทำให้ง่ายขึ้นด้วยเพียง:
member?.someFunction(var someParam);
ฉันขอแนะนำให้คุณอ่านที่นี่: