เครื่องหมายคำถามสองข้อที่รวมกันหมายถึงอะไรใน C #


1629

วิ่งข้ามรหัสบรรทัดนี้:

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

เครื่องหมายคำถามสองข้อหมายความว่าอย่างไร การค้นหาใน Google เป็นเรื่องยาก


50
ไม่ใช่ผู้ประกอบการที่แน่นอน- มีตัวถูกดำเนินการสองตัวเท่านั้น! มันค่อนข้างเหมือนกับตัวดำเนินการตามเงื่อนไข (ซึ่งเป็นไตรภาค) แต่ตัวดำเนินการรวมศูนย์ว่างเป็นตัวดำเนินการแบบไบนารี
Jon Skeet

90
ฉันอธิบายในการสัมภาษณ์ที่ผู้ที่คาดหวังเคยแสดงความสงสัยเกี่ยวกับความสามารถ C # ของฉันเนื่องจากฉันเคยใช้ Java อย่างมืออาชีพมาระยะหนึ่งแล้ว พวกเขาไม่เคยได้ยินมาก่อนและไม่ได้ถามฉันคุ้นเคยกับ C # หลังจากที่ :)
จอน Skeet

77
@Jon Skeet ยังไม่มีมหากาพย์ที่ล้มเหลวในการจดจำทักษะตั้งแต่คนที่ปฏิเสธเดอะบีทเทิลส์ :-) จากนี้ไปเพียงแค่ส่งสำเนาหนังสือของคุณพร้อมลิงก์ URL ไปยังโปรไฟล์ SO ของคุณที่เขียนไว้บนปกด้านใน
ผู้ใช้งานเพื่อความปลอดภัยของผู้ถือ Iain

6
IainMH: สำหรับสิ่งที่คุ้มค่าผมไม่ได้ค่อนข้างเริ่มเขียนหนังสือเล่มนี้เลย (หรือบางทีผมก็ทำงานเกี่ยวกับบทที่ 1 -. สิ่งที่ต้องการ) ยอมรับการค้นหาสำหรับผมที่จะได้พบได้อย่างรวดเร็วบล็อกบทความของฉัน + ฯลฯ
จอน Skeet

7
Re: ประโยคสุดท้ายใน q - สำหรับการอ้างอิงในอนาคต SymbolHound เหมาะสำหรับสิ่งประเภทนี้เช่นsymbolhound.com/?q=%3F%3F&l=&e=&n=&n=กับผู้ที่น่าสงสัยทุกคน ไม่ว่าจะด้วยวิธีใดก็เหมือนเครื่องมือที่ดีเมื่อฉันพบ ... ]
Steve Chambers

คำตอบ:


2154

มันเป็นตัวดำเนินการรวมศูนย์ว่างและค่อนข้างเหมือนกับผู้ประกอบการที่สาม (ทันทีถ้า) ดูยัง?? ผู้ประกอบการ - MSDN

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

ขยายเป็น:

FormsAuth = formsAuth != null ? formsAuth : new FormsAuthenticationWrapper();

ซึ่งเพิ่มเติมขยายไปที่:

if(formsAuth != null)
    FormsAuth = formsAuth;
else
    FormsAuth = new FormsAuthenticationWrapper();

ในภาษาอังกฤษหมายถึง "ถ้าสิ่งใดที่อยู่ทางซ้ายไม่เป็นโมฆะให้ใช้สิ่งนั้นมิฉะนั้นใช้สิ่งที่อยู่ทางขวา"

โปรดทราบว่าคุณสามารถใช้หมายเลขเหล่านี้ตามลำดับ ข้อความต่อไปนี้จะกำหนดคนแรกที่ไม่ใช่ null Answer#ไปAnswer(ถ้าคำตอบทั้งหมดเป็นโมฆะแล้วAnswerเป็นโมฆะ):

string Answer = Answer1 ?? Answer2 ?? Answer3 ?? Answer4;

นอกจากนี้ยังมีมูลค่าการกล่าวขวัญในขณะที่การขยายด้านบนเทียบเท่ากับแนวคิดผลลัพธ์ของแต่ละนิพจน์จะถูกประเมินเพียงครั้งเดียว นี่เป็นสิ่งสำคัญหากตัวอย่างเช่นนิพจน์คือการเรียกใช้เมธอดที่มีผลข้างเคียง (ให้เครดิตกับ @Joey เพื่อชี้เรื่องนี้)


17
อาจเป็นอันตรายต่อโซ่เหล่านี้อาจ
Coops

6
@ CodeBlend เหรอ?
lc

68
@ CodeBlend มันไม่เป็นอันตราย ถ้าคุณจะขยายคุณจะมีชุดของคำสั่ง if / else ที่ซ้อนกัน ไวยากรณ์นั้นแปลกเพราะคุณไม่คุ้นเคยกับมัน
joelmdev

31
มันจะได้รับพระเจ้าส่งว่ามันทำงานสำหรับสตริงที่ว่างเปล่าเช่นกัน :)
Zyphrax

14
@Gusdor ??คือการเชื่อมโยงทางด้านซ้ายเพื่อให้เทียบเท่ากับa ?? b ?? c ?? d ((a ?? b) ?? c ) ?? d"ตัวดำเนินการที่ได้รับมอบหมายและตัวดำเนินการที่ประกอบไปด้วย (? :) เป็นตัวเชื่อมโยงที่ถูกต้องตัวดำเนินการไบนารีอื่น ๆ ทั้งหมดจะอยู่ทางด้านซ้าย" ที่มา: msdn.microsoft.com/en-us/library/ms173145.aspx
ทำเครื่องหมาย E. Haase

284

เพียงเพราะไม่มีใครพูดคำวิเศษ: ยังเป็นผู้ประกอบการโมฆะการรวมตัวกัน มันกำหนดไว้ในส่วน 7.12 ของC # 3.0 สเปคภาษา

มันมีประโยชน์มากโดยเฉพาะอย่างยิ่งเพราะวิธีการทำงานเมื่อใช้หลายครั้งในการแสดงออก การแสดงออกของแบบฟอร์ม:

a ?? b ?? c ?? d

จะให้ผลของการแสดงออกaถ้ามันไม่ใช่ null มิฉะนั้นลองbมิฉะนั้นลองมิฉะนั้นลองc dมันลัดวงจรทุกจุด

นอกจากนี้หากประเภทของdไม่สามารถยกเลิกได้ประเภทของการแสดงออกทั้งหมดจะไม่สามารถยกเลิกได้เช่นกัน


2
ฉันชอบวิธีที่คุณทำให้ความหมายของมันง่ายขึ้นเป็น "ตัวดำเนินการรวมศูนย์ว่าง" นั่นคือทั้งหมดที่ฉันต้องการ
FrankO

2
เป็นไปได้ แต่เกี่ยวข้องกับ: ตอนนี้มันอยู่ใน Swift แต่มันแตกต่างกันมาก: "ผู้ดำเนินการ Nil Coalescing" developer.apple.com/library/ios/documentation/Swift/Conceptual/
......

69

มันเป็นตัวดำเนินการรวมศูนย์ว่าง

http://msdn.microsoft.com/en-us/library/ms173224.aspx

ใช่เกือบจะเป็นไปไม่ได้ที่จะค้นหาเว้นแต่คุณจะรู้ว่ามันคืออะไร :-)

แก้ไข: และนี่คือคุณสมบัติที่ยอดเยี่ยมจากคำถามอื่น คุณสามารถโยงพวกเขา

คุณสมบัติที่ซ่อนของ C #?


33
อย่างน้อยตอนนี้มันง่ายต่อการค้นหาแม้ว่าคุณจะไม่ทราบชื่อฉันเพิ่ง googled "เครื่องหมายคำถามคู่ c #"
stivlo

27

ขอบคุณทุกคนนี่คือคำอธิบายที่กระชับที่สุดที่ฉันพบในเว็บไซต์ MSDN:

// y = x, unless x is null, in which case y = -1.
int y = x ?? -1;

4
คำแนะนำนี้ในแง่มุมที่สำคัญของ ?? ผู้ประกอบการ - มันถูกนำมาใช้เพื่อช่วยในการทำงานกับประเภท nullable ในตัวอย่างของคุณ "x" เป็นประเภท "int?" (Nullable <int>)
Drew Noakes

9
@vitule ไม่มีถ้าตัวถูกดำเนินการที่สองของผู้ประกอบการ null coalescing ไม่เป็น nullable แล้วผลที่ได้คือไม่ใช่ nullable (และ-1เป็นเพียงธรรมดาintซึ่งเป็นที่ไม่ใช่ nullable)
Suzanne Dupéron

ฉันหวังว่ามันจะทำงานได้ดีเช่นนี้ ฉันต้องการทำสิ่งนี้ตลอดเวลา แต่ฉันทำไม่ได้เพราะตัวแปรที่ฉันใช้ไม่ใช่ประเภทที่ไม่มีค่า ทำงานใน coffeescript y = x หรือไม่ -1
PandaWood

@PandaWood ที่จริงคุณทำได้ หากxเป็นประเภทint?แต่yเป็นประเภทintคุณสามารถเขียนint y = (int)(x ?? -1)ได้ มันจะแยกxไปยังintถ้ามันไม่ได้nullหรือกำหนด-1ไปyถ้ามีx null
Johan Wintgens

21

??มีไว้เพื่อให้ค่าสำหรับประเภท nullable เมื่อค่าเป็นโมฆะ ดังนั้นถ้า FormsAuth เป็นโมฆะมันจะส่งคืน FormsAuthenticationWrapper ใหม่ ()


19

ป้อนคำอธิบายรูปภาพที่นี่

เครื่องหมายคำถามสองข้อ (??) ระบุว่าเป็นตัวดำเนินการรวมกัน

การรวมตัวดำเนินการส่งคืนค่า NON-NULL แรกจากเชน คุณสามารถดูวิดีโอ youtube นี้ซึ่งแสดงให้เห็นถึงสิ่งทั้งหมดในทางปฏิบัติ

แต่ให้ฉันเพิ่มสิ่งที่วิดีโอพูดเพิ่ม

หากคุณเห็นความหมายภาษาอังกฤษของการรวมตัวกันมันบอกว่า "รวมเข้าด้วยกัน" ตัวอย่างด้านล่างเป็นรหัสการรวมตัวง่ายซึ่งเชื่อมโยงสี่สาย

ดังนั้นถ้าstr1เป็นnullก็จะพยายามstr2ถ้าstr2เป็นnullก็จะพยายามstr3ไปเรื่อย ๆ จนกว่าจะพบสตริงที่มีค่าที่ไม่ใช่โมฆะ

string final = str1 ?? str2 ?? str3 ?? str4;

กล่าวอย่างง่าย ๆ ว่าโอเปอเรเตอร์ Coalescing ส่งคืนค่า NON-NULL แรกจาก chain


ฉันชอบคำอธิบายนี้เพราะมันมีไดอะแกรมและประโยคสุดท้ายอธิบายมันในแง่ง่าย ๆ ! มันทำให้ง่ายต่อการเข้าใจและเพิ่มความมั่นใจในการใช้งาน ขอบคุณ!
Joshua K

14

มันเป็นมือสั้น ๆ สำหรับผู้ประกอบการที่สาม

FormsAuth = (formsAuth != null) ? formsAuth : new FormsAuthenticationWrapper();

หรือสำหรับผู้ที่ไม่ได้ประกอบไปด้วย:

if (formsAuth != null)
{
  FormsAuth = formsAuth;
}
else
{
  FormsAuth = new FormsAuthenticationWrapper();
}

3
ฉันแก้ไขการสะกดคำว่า "ผู้ประกอบการ" เท่านั้น แต่จริงๆผู้ดำเนินการที่คุณหมายถึงคือผู้ดำเนินการตามเงื่อนไข มันเป็นตัวดำเนินการประกอบไปด้วยคนเดียวใน C # แต่ในบางจุดพวกเขาอาจเพิ่มอีกหนึ่งจุดที่ "ternary" จะคลุมเครือ แต่ "เงื่อนไข" จะไม่
Jon Skeet

มันเป็นการจดชวเลขสำหรับบางสิ่งที่คุณสามารถทำได้กับผู้ประกอบการที่สาม (มีเงื่อนไข) ในรูปแบบที่ยาวของคุณทั้งแบบทดสอบ ( != null) และแบบที่สองformsAuth(หลัง?) อาจเปลี่ยนแปลงได้ ในรูปแบบว่างรวมกันทั้งสองใช้ค่าที่คุณได้ระบุไว้โดยปริยาย
Bob Sammers

12

หากคุณคุ้นเคยกับทับทิมมันก็||=เหมือนกับ C # ??กับฉัน นี่คือทับทิมบางส่วน:

irb(main):001:0> str1 = nil
=> nil
irb(main):002:0> str1 ||= "new value"
=> "new value"
irb(main):003:0> str2 = "old value"
=> "old value"
irb(main):004:0> str2 ||= "another new value"
=> "old value"
irb(main):005:0> str1
=> "new value"
irb(main):006:0> str2
=> "old value"

และใน C #:

string str1 = null;
str1 = str1 ?? "new value";
string str2 = "old value";
str2 = str2 ?? "another new value";

4
x ||= ydesugars กับสิ่งที่ชอบx = x || yดังนั้น??จริง ๆ แล้วคล้ายกับธรรมดา||ในทับทิม
qerub

6
โปรดทราบว่า??เพียงใส่ใจเกี่ยวกับnullในขณะที่||ผู้ประกอบการในรูบีในขณะที่ภาษาส่วนใหญ่เป็นเรื่องเกี่ยวกับnull, falseหรืออะไรที่สามารถได้รับการพิจารณาบูลด้วยค่าตัวfalse(เช่นในบางภาษา"") นี่ไม่ใช่สิ่งที่ดีหรือไม่ดีมีเพียงความแตกต่าง
Tim S.

11

รวมตัวดำเนินการ

มันเทียบเท่ากับ

FormsAuth = formsAUth == null ? new FormsAuthenticationWrapper() : formsAuth

11

ไม่มีอะไรอันตรายเกี่ยวกับเรื่องนี้ ที่จริงแล้วมันสวยงาม คุณสามารถเพิ่มค่าเริ่มต้นได้หากต้องการตัวอย่างเช่น:

รหัส

int x = x1 ?? x2 ?? x3 ?? x4 ?? 0;

1
ดังนั้น x1, x2, x3 และ x4 อาจเป็นประเภทที่มีค่าเป็นโมฆะตัวอย่างเช่น: int? x1 = null;ใช่แล้ว
เควินเมเรดิ ธ

1
@KevinMeredith x1- x4ต้องเป็นประเภท nullable: มันไม่มีเหตุผลที่จะพูดได้อย่างมีประสิทธิภาพ "ผลลัพธ์คือ0ถ้าx4เป็นค่าที่ไม่สามารถใช้" ( null) "ประเภทที่ว่างเปล่า" ที่นี่มีทั้งประเภทค่าที่เป็นโมฆะและประเภทการอ้างอิงแน่นอน เป็นข้อผิดพลาดในการคอมไพล์หากตัวแปรหนึ่งตัวหรือมากกว่าถูกล่ามโซ่ (ยกเว้นอันสุดท้าย) ไม่เป็นโมฆะ
Bob Sammers

11

ชี้เป็นอย่างถูกต้องในคำตอบมากมายที่เป็น "ผู้ประกอบ null หลอมรวม" ( ?? ) พูดซึ่งคุณอาจต้องการตรวจสอบญาติของตน "ผู้ประกอบการ Null เงื่อนไข" ( ?.หรือ? [ ) ที่เป็นผู้ประกอบการที่ หลายครั้งมันถูกใช้ร่วมกับ??

ตัวดำเนินการ Null-conditional

ใช้เพื่อทดสอบหาค่าว่างก่อนดำเนินการการเข้าถึงสมาชิก ( ?. ) หรือดัชนี ( ? [ ) ตัวดำเนินการเหล่านี้ช่วยให้คุณเขียนรหัสน้อยลงเพื่อจัดการกับการตรวจสอบค่าว่าง

ตัวอย่างเช่น:

// if 'customers' or 'Order' property or 'Price' property  is null,
// dollarAmount will be 0 
// otherwise dollarAmount will be equal to 'customers.Order.Price'

int dollarAmount = customers?.Order?.Price ?? 0; 

วิธีเก่าและ?? ในการทำเช่นนี้คือ

int dollarAmount = customers != null 
                   && customers.Order!=null
                   && customers.Order.Price!=null 
                    ? customers.Order.Price : 0; 

ซึ่งเป็น verbose และยุ่งยากมากขึ้น


10

เพื่อความสนุกของคุณเท่านั้น (รู้ว่าคุณคือพวก C # ทั้งหมด ;-)

ฉันคิดว่ามันมีต้นกำเนิดใน Smalltalk ซึ่งมันมีมาหลายปีแล้ว มันถูกกำหนดไว้ที่นั่นเป็น:

ในวัตถุ:

? anArgument
    ^ self

ใน UndefinedObject (คลาส aka ของศูนย์):

? anArgument
    ^ anArgument

มีทั้งการประเมิน (?) และเวอร์ชั่นที่ไม่ผ่านการประเมิน (??)
มันมักจะพบในวิธีการทะเยอทะยานสำหรับตัวแปรเอกชน (ตัวอย่าง) เริ่มต้นขี้เกียจซึ่งถูกปล่อยให้เป็นศูนย์จนจำเป็นจริงๆ


ฟังดูเหมือนจะห่อ ViewState ด้วยคุณสมบัติบน UserControl เริ่มต้นเฉพาะเมื่อได้รับครั้งแรกหากไม่ได้ตั้งไว้ก่อน =)
Seiti

9

ตัวอย่างบางส่วนของการรับค่าโดยใช้การรวมกันที่นี่ไม่มีประสิทธิภาพ

สิ่งที่คุณต้องการคือ:

return _formsAuthWrapper = _formsAuthWrapper ?? new FormsAuthenticationWrapper();

หรือ

return _formsAuthWrapper ?? (_formsAuthWrapper = new FormsAuthenticationWrapper());

สิ่งนี้ป้องกันไม่ให้วัตถุถูกสร้างขึ้นใหม่ทุกครั้ง แทนที่จะเป็นโมฆะตัวแปรส่วนตัวที่เหลือเป็นโมฆะและวัตถุใหม่ที่ถูกสร้างขึ้นในทุก ๆ การร้องขอสิ่งนี้ทำให้มั่นใจได้ว่าจะมีการกำหนดตัวแปรส่วนตัวถ้ามีการสร้างวัตถุใหม่


ไม่ได้??ประเมินทางลัดหรือไม่ new FormsAuthenticationWrapper();มีการประเมินถ้าหากว่า _formsAuthWrapperเป็นศูนย์
MSalters

ใช่นั่นคือประเด็นทั้งหมด คุณต้องการเรียกเมธอดหากตัวแปรนั้นเป็นโมฆะเท่านั้น @MSalters
KingOfHypocrites

8

บันทึก:

ฉันได้อ่านทั้งกระทู้นี้และอื่น ๆ อีกมากมาย แต่ฉันไม่สามารถหาคำตอบอย่างละเอียดได้เช่นนี้

โดยที่ฉันเข้าใจอย่างสมบูรณ์ว่า "ทำไมต้องใช้" และเมื่อใดจึงควรใช้ "และวิธีใช้"

ที่มา:

รากฐานการสื่อสารของ Windows ถูกปลดปล่อยโดย Craig McMurtry ISBN 0-672-32948-4

ชนิดของค่าที่เป็น Nullable

มีสองสถานการณ์ทั่วไปที่หนึ่งต้องการทราบว่ามีการกำหนดค่าให้กับอินสแตนซ์ของประเภทค่าหรือไม่ สิ่งแรกคือเมื่ออินสแตนซ์แสดงถึงค่าในฐานข้อมูล ในกรณีเช่นนี้เราต้องการตรวจสอบอินสแตนซ์เพื่อตรวจสอบว่ามีค่าอยู่ในฐานข้อมูลหรือไม่ สถานการณ์อื่น ๆ ซึ่งเกี่ยวข้องกับเนื้อหาของหนังสือเล่มนี้มากกว่าคือเมื่ออินสแตนซ์แสดงรายการข้อมูลที่ได้รับจากแหล่งข้อมูลระยะไกลบางแห่ง อีกครั้งหนึ่งต้องการพิจารณาจากอินสแตนซ์ว่าได้รับค่าสำหรับรายการข้อมูลนั้นหรือไม่

.NET Framework 2.0 รวมคำจำกัดความชนิดทั่วไปที่ให้สำหรับกรณีเช่นนี้ซึ่งต้องการกำหนดค่า null ให้กับอินสแตนซ์ของประเภทค่าและทดสอบว่าค่าของอินสแตนซ์นั้นเป็นค่าว่างหรือไม่ นิยามประเภททั่วไปนั่นคือ System.Nullable ซึ่ง จำกัด อาร์กิวเมนต์ประเภททั่วไปที่อาจถูกแทนที่สำหรับ T เป็นประเภทค่า อินสแตนซ์ของชนิดที่สร้างจาก System.Nullable สามารถกำหนดค่าเป็น null ได้ แน่นอนค่าของพวกเขาเป็นโมฆะโดยค่าเริ่มต้น ดังนั้นประเภทที่สร้างขึ้นจาก System.Nullable อาจจะเรียกว่าเป็นประเภทค่า nullable System.Nullable มีคุณสมบัติ Value ซึ่งค่าที่กำหนดให้กับอินสแตนซ์ของประเภทที่สร้างจากมันสามารถรับได้หากค่าของอินสแตนซ์ไม่เป็นโมฆะ ดังนั้นหนึ่งสามารถเขียน:

System.Nullable<int> myNullableInteger = null;
myNullableInteger = 1;
if (myNullableInteger != null)
{
Console.WriteLine(myNullableInteger.Value);
}

ภาษาการเขียนโปรแกรม C # มีไวยากรณ์แบบย่อสำหรับการประกาศประเภทที่สร้างจาก System.Nullable ไวยากรณ์นั้นอนุญาตให้หนึ่งย่อ:

System.Nullable<int> myNullableInteger;

ถึง

int? myNullableInteger;

คอมไพเลอร์จะป้องกันไม่ให้หนึ่งพยายามกำหนดค่าของประเภทค่า nullable กับประเภทค่าสามัญด้วยวิธีนี้:

int? myNullableInteger = null;
int myInteger = myNullableInteger;

มันป้องกันหนึ่งจากการทำเช่นนั้นเพราะประเภทค่า nullable สามารถมีค่า null ซึ่งจริงจะมีในกรณีนี้และค่าที่ไม่สามารถกำหนดให้กับประเภทค่าสามัญ แม้ว่าคอมไพเลอร์จะอนุญาตรหัสนี้

int? myNullableInteger = null;
int myInteger = myNullableInteger.Value;

คำสั่งที่สองจะทำให้เกิดข้อยกเว้นจะถูกโยนเพราะความพยายามในการเข้าถึง System.Nullable.Value คุณสมบัติเป็นการดำเนินการที่ไม่ถูกต้องหากประเภทที่สร้างจาก System.Nullable ยังไม่ได้รับการกำหนดค่าที่ถูกต้องของ T ซึ่งไม่ได้เกิดขึ้นในนี้ กรณี.

สรุป:

วิธีหนึ่งที่เหมาะสมในการกำหนดค่าของชนิดค่า nullable ให้กับชนิดค่าปกติคือการใช้คุณสมบัติ System.Nullable.HasValue เพื่อตรวจสอบว่าค่าที่ถูกต้องของ T ถูกกำหนดให้กับชนิดค่า nullable หรือไม่:

int? myNullableInteger = null;
if (myNullableInteger.HasValue)
{
int myInteger = myNullableInteger.Value;
}

ตัวเลือกอื่นคือการใช้ไวยากรณ์นี้:

int? myNullableInteger = null;
int myInteger = myNullableInteger ?? -1;

โดยที่ myInteger จำนวนเต็มสามัญจะถูกกำหนดค่าของจำนวนเต็ม null "myNullableInteger" ถ้าหลังได้รับมอบหมายค่าจำนวนเต็มที่ถูกต้อง; มิฉะนั้น myInteger จะถูกกำหนดค่าเป็น -1


1

มันเป็นตัวดำเนินการรวมศูนย์ว่างที่ทำงานคล้ายกับตัวดำเนินการแบบไตรภาค

    a ?? b  => a !=null ? a : b 

อีกจุดที่น่าสนใจสำหรับเรื่องนี้คือ "ประเภท nullable สามารถมีค่าหรืออาจจะไม่ได้กำหนด" ดังนั้นถ้าคุณพยายามที่จะกำหนดประเภทของค่าที่เป็นโมฆะให้เป็นประเภทของค่าที่ไม่เป็นโมฆะคุณจะได้รับข้อผิดพลาดในการรวบรวม

int? x = null; // x is nullable value type
int z = 0; // z is non-nullable value type
z = x; // compile error will be there.

ดังนั้นจะทำอย่างไรโดยใช้ ?? ผู้ประกอบการ:

z = x ?? 1; // with ?? operator there are no issues

1
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

เทียบเท่ากับ

FormsAuth = formsAuth != null ? formsAuth : new FormsAuthenticationWrapper();

แต่สิ่งที่ยอดเยี่ยมเกี่ยวกับเรื่องนี้ก็คือคุณสามารถโยงมันได้เหมือนกับที่คนอื่นพูด คนที่ไม่ได้สัมผัสก็คือคุณสามารถใช้มันเพื่อโยนข้อยกเว้น

A = A ?? B ?? throw new Exception("A and B are both NULL");

เป็นเรื่องที่ดีมากที่คุณรวมตัวอย่างไว้ในโพสต์ของคุณแม้ว่าคำถามจะมองหาคำอธิบายว่าโอเปอเรเตอร์คืออะไรหรือทำอะไร
TGP1994

1

??ผู้ประกอบการจะเรียกว่าผู้ประกอบการด้วย null coalescing มันจะส่งกลับตัวถูกดำเนินการทางซ้ายถ้าตัวถูกดำเนินการไม่เป็นโมฆะ มิฉะนั้นจะส่งคืนตัวถูกดำเนินการทางขวา

int? variable1 = null;
int variable2  = variable1 ?? 100;

ตั้งvariable2ค่าเป็นvariable1ถ้าvariable1ไม่ใช่โมฆะ มิฉะนั้นถ้าvariable1 == nullตั้งvariable2เป็น 100


0

คนอื่นได้อธิบายNull Coalescing Operatorค่อนข้างดี สำหรับผู้ที่สนใจมีไวยากรณ์สั้นลงที่นี้ (คำถาม SO):

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

เทียบเท่ากับสิ่งนี้:

FormsAuth ??= new FormsAuthenticationWrapper();

บางคนพบว่าอ่านง่ายและสั้นกระชับ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.