2009-10-09 15 views
36

मुझे हाल ही में पता चला है कि हम इसका उपयोग कर सकते हैं ?? नल की जांच करने के लिए ऑपरेटर। जांच करें नीचे दिए गए कोड नमूने:हम क्यों पसंद करते हैं? सेवा मेरे ?? सी # में ऑपरेटर?

var res = data ?? new data(); 

यह ठीक करने के लिए

var res = (data==null) ? new data() : data ; 

मैं अपने पूरी परियोजना स्रोत भंडार और अन्य ओपन सोर्स प्रोजेक्ट में से कुछ की जाँच की समान है। और यह ?? ऑपरेटर का कभी भी उपयोग नहीं किया गया।

मुझे आश्चर्य है कि इसके पीछे कोई कारण है, जैसे कि प्रदर्शन की समस्याएं या कुछ?

संपादित करें:

मैं सिर्फ पुनरावर्ती & एंटोन से टिप्पणी के आधार पर मेरी नमूना कोड अपडेट किया गया। लापरवाही में यह एक गलती है। :(

+21

एक कारण है कि पीपीएल को पता नहीं हो सकता है! – vpram86

+1

"var res = (data! = Null) होना चाहिए? डेटा: नया डेटा();" आपके नमूने में –

+2

@ रूबेन्स, बस मूर्ख और सही नहीं। – kenny

उत्तर

53

अशक्त सम्मिलित ऑपरेटर जब अशक्त के लिए जाँच, कि इसका मुख्य उद्देश्य है अधिक स्पष्ट है। यह भी श्रृंखलित जा सकता है।

object a = null; 
object b = null; 
object c = new object(); 
object d = a ?? b ?? c; //d == c. 

कि ऑपरेटर जाँच शून्य पर सीमित है, त्रिगुट ऑपरेटर है नहीं। उदाहरण के लिए

bool isQuestion = true; 
string question = isQuestion ? "Yes" : "No"; 

मुझे लगता है। लोग सिर्फ अशक्त सम्मिलित ऑपरेटर के बारे में पता है तो वे बजाय त्रिगुट ऑपरेटर का उपयोग नहीं कर रहे हैं, इसलिए यदि आप सी # के अंदर पता नहीं है त्रिगुट पहले सी सबसे सी शैली भाषाओं में # अस्तित्व में और बाहर और/या आप किसी अन्य भाषा में प्रोग्राम किया, ते rnary एक प्राकृतिक पसंद है। यदि आप शून्य के लिए जांच कर रहे हैं, तो नल कोलेसे ऑपरेटर का उपयोग करें, यह इसके लिए डिज़ाइन किया गया है, और आईएल थोड़ा अनुकूलित है (तुलना करें ?? अगर किसी और के लिए)।

यहाँ एक उदाहरण से प्रत्येक

object a = null; 
object b = null; 
object c = null; 

object nullCoalesce = a ?? b ?? c; 

object ternary = a != null ? a : b != null ? b : c; 

object ifThenElse; 

if (a != null) 
    ifThenElse = a; 
else if (b != null) 
    ifThenElse = b; 
else if (c != null) 
    ifThenElse = c; 

सबसे पहले उपयोग की तुलना है, बस अशक्त सम्मिलित वाक्य विन्यास को देखो, यह जिस तरह से स्पष्ट है। टर्नरी वास्तव में भ्रमित है। अब देता है आईएल पर देखने

अशक्त संगठित होना केवल

.entrypoint 
.maxstack 2 
.locals init (
    [0] object a, 
    [1] object b, 
    [2] object c, 
    [3] object nullCoalesce) 
L_0000: ldnull 
L_0001: stloc.0 
L_0002: ldnull 
L_0003: stloc.1 
L_0004: newobj instance void [mscorlib]System.Object::.ctor() 
L_0009: stloc.2 
L_000a: ldloc.0 
L_000b: dup 
L_000c: brtrue.s L_0015 
L_000e: pop 
L_000f: ldloc.1 
L_0010: dup 
L_0011: brtrue.s L_0015 
L_0013: pop 
L_0014: ldloc.2 
L_0015: stloc.3 
L_0016: ldloc.3 
L_0017: call void [mscorlib]System.Console::WriteLine(object) 
L_001c: ret 

त्रिगुट केवल

.entrypoint 
.maxstack 2 
.locals init (
    [0] object a, 
    [1] object b, 
    [2] object c, 
    [3] object ternary) 
L_0000: ldnull 
L_0001: stloc.0 
L_0002: ldnull 
L_0003: stloc.1 
L_0004: newobj instance void [mscorlib]System.Object::.ctor() 
L_0009: stloc.2 
L_000a: ldloc.0 
L_000b: brtrue.s L_0016 
L_000d: ldloc.1 
L_000e: brtrue.s L_0013 
L_0010: ldloc.2 
L_0011: br.s L_0017 
L_0013: ldloc.1 
L_0014: br.s L_0017 
L_0016: ldloc.0 
L_0017: stloc.3 
L_0018: ldloc.3 
L_0019: call void [mscorlib]System.Console::WriteLine(object) 
L_001e: ret 

तो फिर वरना केवल

.entrypoint 
.maxstack 1 
.locals init (
    [0] object a, 
    [1] object b, 
    [2] object c, 
    [3] object ifThenElse) 
L_0000: ldnull 
L_0001: stloc.0 
L_0002: ldnull 
L_0003: stloc.1 
L_0004: newobj instance void [mscorlib]System.Object::.ctor() 
L_0009: stloc.2 
L_000a: ldloc.0 
L_000b: brfalse.s L_0011 
L_000d: ldloc.0 
L_000e: stloc.3 
L_000f: br.s L_001a 
L_0011: ldloc.1 
L_0012: brfalse.s L_0018 
L_0014: ldloc.1 
L_0015: stloc.3 
L_0016: br.s L_001a 
L_0018: ldloc.2 
L_0019: stloc.3 
L_001a: ldloc.3 
L_001b: call void [mscorlib]System.Console::WriteLine(object) 
L_0020: ret 

आईएल मेरी मजबूत बिंदुओं में से एक नहीं है, तो शायद कोई मेरा जवाब संपादित कर सकता है और उस पर विस्तार कर सकता है। मैं अपने सिद्धांत की व्याख्या करने जा रहा था, लेकिन मैं खुद को और दूसरों को भ्रमित नहीं करना चाहता था। एलओसी की संख्या सभी तीनों के लिए समान है, लेकिन सभी आईएल ऑपरेटरों को निष्पादित करने के लिए समान समय नहीं लगता है।

+7

यह * * टर्नरी ऑपरेटर नहीं है, यह सिर्फ * एक * टर्नरी ऑपरेटर है। आप जो संदर्भित करते हैं उसे ** सशर्त ऑपरेटर ** कहा जाता है। –

+1

@ बॉब, यह एक अच्छी तुलना है ... coalesce ऑपरेटर सभी से बेहतर है जब हम नल के साथ सौदा करते हैं ... – RameshVel

+3

@divo: ठीक है यह सी #: पी – Lucas

6

एक कारण मैं सोच सकता हूं कि यह ऑपरेटर .NET 2.0 में पेश किया गया था, इसलिए .NET 1.1 के लिए कोड नहीं हो सकता है।

मैं आपसे सहमत हूं, हमें इसे और अधिक बार उपयोग करना चाहिए।

रेफरी link

12

??ऑपरेटर (null-coalescing operator के रूप में भी जाना जाता है) टर्नरी ऑपरेटर से कम ज्ञात है, क्योंकि यह .NET 2.0 और Nullable प्रकारों के साथ अपनी शुरुआत की गई है। इसका उपयोग न करने के कारणों में शायद यह पता नहीं होना चाहिए कि यह मौजूद है, या टर्नरी ऑपरेटर से अधिक परिचित है।

उस ने कहा, शून्य की जांच केवल एकमात्र चीज नहीं है जिसके लिए टर्नरी ऑपरेटर अच्छा है, इसलिए यह एक बहुत ही विशिष्ट आवश्यकता के लिए बेहतर विकल्प की तरह नहीं है। :)

1

मुझे लगता है कि यह सिर्फ अन्य भाषाओं की आदत है। AFAIK, ?? ऑपरेटर का उपयोग किसी अन्य भाषा में नहीं किया जाता है।

+2

मुझे पता है कि यह बहुत पुराना है, लेकिन मैं टिप्पणी करना चाहता था और कहता हूं कि यह भी पर्ल में v5.10 के रूप में उपयोग किया जाता है, केवल '//' '' '' '' '' '' '' 'के साथ होता है। एक उदाहरण ([विकिपीडिया] से लिया गया है (http://en.wikipedia.org/wiki/Null_coalescing_operator#Perl)): '$ संभावित_null_value // $ value_if_null' –

0

मैं सोचा होगा

var res = data ?? data.toString(); 

के बराबर होगा

var res = (data!=null) ? data : data.toString(); 
2

एक कारण यह है (के रूप में दूसरों को पहले से ही छुआ है) जागरूकता की कमी होने की संभावना है। यह भी हो सकता है (जैसा कि मेरे अपने मामले में), दृष्टिकोण की संख्या को कोड आधार में जितनी ज्यादा हो सके उतनी चीजों को करने की इच्छा रखने की इच्छा है। तो मैं सभी कॉम्पैक्ट के लिए टर्नरी ऑपरेटर का उपयोग करता हूं अगर एक शर्त-से-मेट-डू-यह-अन्यथा-वह-स्थितियां हैं।

उदाहरण के लिए, मैं निम्नलिखित दो बयान नहीं बल्कि एक वैचारिक स्तर पर समान लगता है:

return a == null ? string.Empty : a;  
return a > 0 ? a : 0; 
4

आधार पर Bob's जवाब

public object nullCoalesce(object a, object b, object c) 
{ 
    return a ?? b ?? c; 
} 
public object ternary(object a, object b, object c) 
{ 
    return a != null ? a : b != null ? b : c; 
} 
public object ifThenElse(object a, object b, object c) 
{ 
    if (a != null) 
     return a; 
    else if (b != null) 
     return b; 
    else 
     return c; 
} 

... इस आईएल रिहाई बनाता से है ..

.method public hidebysig instance object nullCoalesce(
    object a, 
    object b, 
    object c) cil managed 
{ 
    .maxstack 8 
    L_0000: ldarg.1 
    L_0001: dup 
    L_0002: brtrue.s L_000b 
    L_0004: pop 
    L_0005: ldarg.2 
    L_0006: dup 
    L_0007: brtrue.s L_000b 
    L_0009: pop 
    L_000a: ldarg.3 
    L_000b: ret 
} 

.method public hidebysig instance object ternary(
    object a, 
    object b, 
    object c) cil managed 
{ 
    .maxstack 8 
    L_0000: ldarg.1 
    L_0001: brtrue.s L_000a 
    L_0003: ldarg.2 
    L_0004: brtrue.s L_0008 
    L_0006: ldarg.3 
    L_0007: ret 
    L_0008: ldarg.2 
    L_0009: ret 
    L_000a: ldarg.1 
    L_000b: ret 
} 

.method public hidebysig instance object ifThenElse(
    object a, 
    object b, 
    object c) cil managed 
{ 
    .maxstack 8 
    L_0000: ldarg.1 
    L_0001: brfalse.s L_0005 
    L_0003: ldarg.1 
    L_0004: ret 
    L_0005: ldarg.2 
    L_0006: brfalse.s L_000a 
    L_0008: ldarg.2 
    L_0009: ret 
    L_000a: ldarg.3 
    L_000b: ret 
} 
संबंधित मुद्दे