c# बेस क्लास कंस्ट्रक्टर में सेट होने पर ओवरराइड की गई केवल-प्रॉपर्टी ही शून्य क्यों रहती है?




automatic-properties (2)

मैंने निम्नलिखित उदाहरण की कोशिश की:

public class TestBase
{
    public virtual string ReadOnly { get; }

    public TestBase()
    {
        ReadOnly = "from base";
    }
}

class Test : TestBase
{
    public override string ReadOnly { get; }
    public Test()
    {
        // nothing here
    }
}

जब मैं टेस्ट का एक उदाहरण बनाता हूं, तो मैं देखता हूं कि ReadOnly शून्य रहता है। पर क्यों? मैं वास्तव में इसे लटका नहीं पाता, क्या कोई मुझे समझा सकता है कि ऐसा क्यों होता है? कम से कम मैं एक त्रुटि की उम्मीद करूंगा, कि केवल पढ़ने वाली संपत्ति के मालिक वर्ग के बाहर सेट नहीं किया जा सकता है।


इसे समझाने का सबसे आसान तरीका यह विचार करना है कि इसे लागू करने के लिए संकलक किस कोड को उत्पन्न कर रहा है।

आधार वर्ग इसके बराबर है:

public class TestBase
{
    public virtual string ReadOnly => _testBaseReadOnly;

    public TestBase()
    {
        _testBaseReadOnly = "from base";
    }

    readonly string _testBaseReadOnly;
}

व्युत्पन्न वर्ग इसके बराबर है:

class Test : TestBase
{
    public override string ReadOnly => _testReadOnly;

    readonly string _testReadOnly;
}

यहां ध्यान देने वाली महत्वपूर्ण बात यह है कि व्युत्पन्न वर्ग के पास रीडऑनली के लिए अपना खुद का आधार है - यह आधार वर्ग से एक का फिर से उपयोग नहीं करता है।

यह महसूस करने के बाद, यह स्पष्ट होना चाहिए कि ओवरराइड की गई संपत्ति क्यों शून्य है।

ऐसा इसलिए है क्योंकि व्युत्पन्न वर्ग के पास ReadOnly लिए अपना स्वयं का बैकिंग फ़ील्ड है, और इसके निर्माता उस बैकिंग फ़ील्ड को इनिशियलाइज़ नहीं कर रहे हैं।

संयोग से, यदि आप Resharper का उपयोग कर रहे हैं, तो यह वास्तव में आपको चेतावनी देगा कि आप व्युत्पन्न वर्ग में ReadOnly सेट नहीं कर रहे हैं:

 "Get-only auto-property 'ReadOnly' is never assigned."

संकलक इसे नीचे के रूप में मानता है; मूल रूप से, कंस्ट्रक्टर में कोड TestBase बैक में मूल समर्थन क्षेत्र को TestBase । ऐसा लगता है कि आपका एक समर्थित परिदृश्य नहीं है, लेकिन ... मुझे आश्चर्य है कि क्या भाषा टीम ने इस मामले पर विचार किया है।

BTW: यदि आप कभी भी देखना चाहते हैं कि संकलक कोड के साथ क्या करता है: sharplab.io

public class TestBase
{
    [CompilerGenerated]
    private readonly string <ReadOnly>k__BackingField; // note: not legal in "real" C#

    public virtual string ReadOnly
    {
        [CompilerGenerated]
        get
        {
            return <ReadOnly>k__BackingField; // the one in TestBase
        }
    }

    public TestBase()
    {
        <ReadOnly>k__BackingField = "from base";
    }
}
internal class Test : TestBase
{
    [CompilerGenerated]
    private readonly string <ReadOnly>k__BackingField;

    public override string ReadOnly
    {
        [CompilerGenerated]
        get
        {
            return <ReadOnly>k__BackingField; // the one in Test
        }
    }
}






automatic-properties