प्रश्न चिह्न और डॉट ऑपरेटर क्या है? C # 6.0 में मतलब है?


359

VS2015 पूर्वावलोकन में C # 6.0 के साथ हमारे पास एक नया ऑपरेटर है ?., जिसका उपयोग इस तरह किया जा सकता है:

public class A {
   string PropertyOfA { get; set; }
}

...

var a = new A();
var foo = "bar";
if(a?.PropertyOfA != foo) {
   //somecode
}

यह वास्तव में क्या करता है?

जवाबों:


499

यह अशक्त सशर्त संचालक है। इसका मूल रूप से मतलब है:

"पहले ऑपरेंड का मूल्यांकन करें; यदि यह अशक्त है, तो शून्य के परिणामस्वरूप बंद करो। अन्यथा, दूसरे ऑपरेंड (पहले ऑपरेंड के एक सदस्य की पहुंच के रूप में) का मूल्यांकन करें।"

आपके उदाहरण में, मुद्दा यह है कि यदि aहै null, तो एक अपवाद को फेंकने के बजाय a?.PropertyOfAमूल्यांकन करेगा null- यह तब उस nullसंदर्भ की तुलना करेगा foo(स्ट्रिंग के ==अधिभार का उपयोग करके ), यह पता लगाएं कि वे समान नहीं हैं और निष्पादन ifविवरण के शरीर में जाएगा। ।

दूसरे शब्दों में, यह इस तरह है:

string bar = (a == null ? null : a.PropertyOfA);
if (bar != foo)
{
    ...
}

... इसके अलावा aकेवल एक बार मूल्यांकन किया जाता है।

ध्यान दें कि यह अभिव्यक्ति के प्रकार को भी बदल सकता है। उदाहरण के लिए, विचार करें FileInfo.Length। यह एक प्रकार की संपत्ति है long, लेकिन यदि आप इसे शून्य सशर्त ऑपरेटर के साथ उपयोग करते हैं, तो आप प्रकार की अभिव्यक्ति के साथ समाप्त होते हैं long?:

FileInfo fi = ...; // fi could be null
long? length = fi?.Length; // If fi is null, length will be null

8
क्या इसे अशक्त सशर्त संचालक नहीं कहा जाता है ?
SLaks

1
@ एसएलएस: मुझे लगा कि यह "सशर्त अशक्त" है लेकिन मैं गलत हो सकता हूं। पिछली बार जब मैंने रोज़लिन भाषा के डॉक्स की जाँच की, तो उसका नाम भी नहीं बदला गया था। शायद स्रोत यहां प्राधिकरण है - जांच करेगा।
जॉन स्कीट

3
@ एसएलएसी: निश्चित। SyntaxKind में यह जाहिरा तौर पर ConditionalAccessExpression है जो नाराज़गी से दोनों में से एक भी नहीं है ...
जॉन स्कीट

12
मैंने नाम "एल्विस" ऑपरेटर को पसंद किया: पी
अहमद इलियास

3
बस रिकॉर्ड के लिए मैंने इस ऑपरेटर के लिए पांच अलग-अलग नाम देखे हैं: सुरक्षित नेविगेशन, अशक्त-सशर्त, अशक्त प्रचार, सशर्त पहुंच, एल्विस।
गिगी

81

एक पदानुक्रम और / या मानचित्रण वस्तुओं को समतल करते समय यह बहुत उपयोगी हो सकता है। के बजाय:

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);

DotNetField उदाहरण :

सिस्टम का उपयोग;

public class Program
{
  public static void Main()
  {
    Action<string> consoleWrite = null;

    consoleWrite?.Invoke("Test 1");

    consoleWrite = (s) => Console.WriteLine(s);

    consoleWrite?.Invoke("Test 2");
  }
}

परिणाम:

परीक्षण २


27
लोगों को बचाने के लिए क्या देख रहे हो ?? है .. यह अशक्त-सहवर्ती ऑपरेटर है और नाम वापस कर देगा यदि यह अशक्त नहीं है, अन्यथा यह "एन / ए" लौटाएगा।
स्टीव

6
@ एरिक फिलिप्स मुझे लगता है कि आपको || Model.Model2.Model3.Model4.Name == null एक ही तर्क जोड़ने की आवश्यकता है , अन्यथा मामले Model.Model2.Model3.Model4.Nameमें null, mapped.Nameरहेगाnull
RazvanR

2
@ErikPhilips उसी पृष्ठ पर नहीं जिस पर मुझे लगता है। कृपया यह देखने की कोशिश करें कि यदि आपके दोनों मामलों में क्या होता Model.Model2.Model3.Model4.Nameहै null
रज़वान

1
परिणाम "एन / ए" है, फिर से पहले टिप्पणी पर ध्यान दें। DotNetFiddle.Net कार्य उदाहरण
एरिक फिलिप्स

7
@ ErikPhilips: जिसमें पहली टिप्पणी के साथ कुछ भी नहीं है, क्योंकि यह आपके पहले उदाहरण से संबंधित नहीं है। इसमें आप else-ब्रांच में कूदेंगे और आपके पास mapped.Name = Model.Model2.Model3.Model4.Name -> mapped.Name = nullदूसरा उदाहरण होगा mapped.Name = "N/A"। देखें संपादित DotNetFiddle
केंचुल

3

यह C # के लिए अपेक्षाकृत नया है, जो हमारे लिए कार्यप्रणाली में अशक्त या गैर-शून्य मूल्यों के संबंध में फ़ंक्शन को कॉल करना आसान बनाता है ।

उसी चीज़ को हासिल करने का पुराना तरीका था:

var functionCaller = this.member;
if (functionCaller!= null)
    functionCaller.someFunction(var someParam);

और अब इसे बहुत आसान बना दिया गया है:

member?.someFunction(var someParam);

मैं आपको इसे यहाँ पढ़ने की जोरदार सलाह देता हूँ:

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.