अशक्त <int> बनाम int? - क्या कोई अंतर है?


93

जाहिर है Nullable<int>और int?मूल्य में बराबर हैं। क्या किसी एक को दूसरे पर चुनने का कोई कारण है?

Nullable<int> a = null;
int? b = null;
a == b; // this is true

जवाबों:


134

कोई फर्क नहीं।

int?सिर्फ शॉर्टहैंड है Nullable<int>, जो खुद के लिए शॉर्टहैंड है Nullable<Int32>।

संकलित कोड वही होगा जो आप उपयोग करने के लिए चुनते हैं।


1
दुर्भाग्य से कुछ कोने मामले हैं जब यह सख्ती से सच नहीं है। इस जवाब को देखें ।
— क़ुबेक

22

?प्रपत्र सिर्फ पूर्ण प्रकार के लिए एक आशुलिपि है। व्यक्तिगत पसंद ही एक दूसरे पर एक चुनने का एकमात्र कारण है।

पूरी जानकारी यहाँ ।

सिंटैक्स T?शॉर्टहैंड है Nullable<T>, जहां Tएक वैल्यू टाइप है। दो रूप विनिमेय हैं।


18

जब मैं पूरी तरह से सहमत हैं कि ज्यादातर मामलों में वे एक ही हैं, मैं हाल ही में एक ऐसी स्थिति में आए जब वहाँ है उन दोनों के बीच एक अंतर है। इस विवरण को देखने के लिए , लेकिन यहां आपको एक त्वरित उदाहरण देने के लिए:

void Test<T>(T a, bool b)
{
    var test = a is int? & b;              // does not compile
    var test2 = a is Nullable<int> & b;    // does compile
}

पहली पंक्ति निम्न त्रुटि संदेश देती है:

error CS1003: Syntax error, ':' expected 
error CS1525: Invalid expression term ';'

यदि आप इसके सटीक कारण के बारे में उत्सुक हैं, तो मैं वास्तव में आपको पहले से जुड़े प्रश्न की जांच करने की सलाह देता हूं , लेकिन मूल समस्या यह है कि एक is(या as) ऑपरेटर के बाद पार्सिंग चरण में , जब हम एक ?टोकन का सामना करते हैं, तो हम अगले की जांच करते हैं टोकन कर सकते हैं (एक एकल ऑपरेटर के रूप में व्याख्या की जा &एक हो सकता है) और अगर ऐसा है: पार्सर की संभावना के बारे में परवाह नहीं करता ?टोकन एक प्रकार संशोधक किया जा रहा है, यह बस उसे पहले प्रकार का उपयोग करता है, और बाकी को पार्स होगा, जैसे कि ?टोकन एक टर्नरी ऑपरेटर थे (इस प्रकार पार्सिंग विफल हो जाएगा)।

इसलिए, सामान्य तौर पर int?और Nullable<int>विनिमेय होने पर, कुछ कोने मामले होते हैं जब वे पूरी तरह से अलग परिणाम देते हैं, क्योंकि पार्सर आपके कोड को कैसे देखता है।


2
पहला मामला, testकोष्ठक के साथ तय किया गया है, इसलिए var test = (a is int?) & b;। यह भी तय किया जा सकता है var test = a is int? && b;, और यह देखते हुए कि bएक साधारण मूल्य पैरामीटर (मूल्यांकन पर कोई साइड इफेक्ट) इसे प्राथमिकता देते अजीब लगता है &खत्म हो गया &&।
— जेपी स्टिग नील्सन

उस विशेष वाक्यविन्यास में, ?एक प्रमुख चरित्र है।
— पीट गराफानो

लिंक किए गए प्रश्न और उत्तर देखें, आपकी टिप्पणियों को सभी वहां संबोधित किया गया है :) मैंने अभी इस जानकारी को यहां जोड़ा है, जैसा कि मैंने महसूस किया कि यह प्रासंगिक है, क्योंकि यह दो रूपों के बीच एक अंतर लाता है, और यह साबित करता है कि यह सिर्फ वाक्यगत चीनी नहीं है
— qqbenq

जेपी सही है। यह संकलन नहीं है क्योंकि यह int?एक टर्नरी ऑपरेशन ( var test = a is int? <return if true> : <return if false>) के रूप में व्याख्या कर रहा है , एक अशक्त इंट नहीं।
— लेवी फुलर

1
@LeviFuller (जारी) इन विशेष boolअधिभार के लिए दस्तावेज देखें । ये बूलियन लॉजिकल ऑपरेटर्स ( &फॉर bool) और बुलियन कंडीशनल लॉजिकल ऑपरेटर्स ( &&फॉर bool) हैं। ध्यान दें कि इन उप-वर्गों में से पहला स्पष्ट रूप से तार्किक नाम कैसे है । याद रखें, C # में boolऔर संख्यात्मक प्रकारों के बीच कोई रूपांतरण ("कास्ट") नहीं है !
— जेपी स्टिग नील्सन

6

कोड-प्रथम एंटिटी फ्रेमवर्क (EF) पीढ़ी का उपयोग करते समय स्पष्ट रूप से दोनों के बीच अंतर होता है:

जब आपकी इकाई में घोषित संपत्ति होती है जैसे:

public class MyEntity
{
    public Nullable<int> MyNullableInt { get; set; } 
}

EF एक अशक्त संपत्ति उत्पन्न नहीं करेगा और आपको जनरेटर को मजबूर करना होगा ताकि वह इसे अशक्त कर सके:

public class YourContext : DbContext
{
    public DbSet<MyEntity> MyEntities{ get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<MyEntity>().Property(x => x.MyNullableInt).IsOptional();
    }
}

दूसरी ओर, यदि आप अपनी इकाई की घोषणा करते हैं जैसे:

public class MyEntity
{
     public int? MyNullableInt { get; set; }
}

EF जनरेटर संबंधित डेटाबेस तालिका में एक अशक्त क्षेत्र के साथ एक अशक्त संपत्ति उत्पन्न करेगा।


2
यह वास्तव में दुर्भाग्यपूर्ण है।
— सिराइड करें

8
इससे पता चलता है कि आपकी Nullableकहीं और परिभाषा है, क्योंकि बिल्ट-इन के साथ Nullable<T>, यह ईएफ के लिए दोनों के बीच अंतर को देखना संभव नहीं है। यहां तक ​​कि अगर ईएफ लोग उन्हें अलग तरह से इलाज करना चाहते थे, तो वे नहीं कर सकते थे।

1
क्या किसी ने पुष्टि की है कि यह मामला है? (नकारात्मक वोटों के कारण बस थोड़ा सतर्क रहें)
— रेवल्वेस

@RayL नहीं यह मामला नहीं है। यह उत्तर सही नहीं है और जैसा कि एचवीडी ने बताया, असंभव है।
— जूता

1
यह देखते हुए कि ईएफ कोड कोड टेम्पलेट्स का उपयोग करके उत्पन्न होता है, यह वास्तव में संभव हो सकता है। मेरा जवाब मेरे अनुभव पर आधारित है और मैंने जो बदलाव का सुझाव दिया था वह उस मुद्दे को तय करता है जो मैं कर रहा था। इसके अलावा, ऐसा लगता है कि कुछ लोगों ने पाया कि यह वास्तव में अप-वोट पर आधारित मामला है।
— मेसिएज

2

अशक्त एक सामान्य प्रकार है, लेकिन int? नहीं है।

कुछ परिदृश्य हैं जहां अशक्त इंट का उपयोग किया जाना चाहिए ?

उदाहरण के लिए: यहां आप Nullable को int से बदल नहीं सकते हैं ?

Nullable का उपयोग किए बिना आप नीचे दिए गए कोड को कैसे बदल सकते हैं ?

class LazyValue<T> where T : struct
{
   private Nullable<T> val;
   private Func<T> getValue;

   // Constructor.
   public LazyValue(Func<T> func)
   {
      val = null;
      getValue = func;
   }

   public T Value
   {
      get
      {
         if (val == null)
            // Execute the delegate.
            val = getValue();
         return (T)val;
      }
   }
}

3
अगर यह सवाल जेनेरिक प्रकारों के बारे में पूछ रहा है, तो कोई बात नहीं हो सकती है, लेकिन इस सवाल ने इंट को निर्दिष्ट कर दिया है, इसलिए ऐसा नहीं Nullable<T>हैNullable<int>
— एंड्रयू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.