Why does an overridden get-only property stay null when set in base class constructor?











up vote
38
down vote

favorite
2












I tried the following example:



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
}
}


When I create an instance of Test, I see that ReadOnly stays null. But why?
I really do not get the hang of it, could somebody please explain to me why this happens? At least I would expect and error, that a read-only property cannot be set outside of the owning class.










share|improve this question




















  • 1




    @SeM It's not really a duplicate, since this question is about the affect that overriding the string property is having.
    – Matthew Watson
    Nov 30 at 11:04










  • @MatthewWatson you're talking about first or second one?
    – SeM
    Nov 30 at 11:04






  • 2




    @SeM Both, because neither of those answers talk about overriding properties.
    – Matthew Watson
    Nov 30 at 11:06






  • 2




    I think it's related to that and virtual member access in constructor, no? Though it's clear if you look at how it's compiled: both classes get their own private backing field. The one in the child class gets returned. sharplab.io/…
    – pinkfloydx33
    Nov 30 at 11:07






  • 2




    For bonus points, add Console.WriteLine(ReadOnly); in the base constructor, after assigning to the property.
    – Lasse Vågsæther Karlsen
    Nov 30 at 11:34















up vote
38
down vote

favorite
2












I tried the following example:



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
}
}


When I create an instance of Test, I see that ReadOnly stays null. But why?
I really do not get the hang of it, could somebody please explain to me why this happens? At least I would expect and error, that a read-only property cannot be set outside of the owning class.










share|improve this question




















  • 1




    @SeM It's not really a duplicate, since this question is about the affect that overriding the string property is having.
    – Matthew Watson
    Nov 30 at 11:04










  • @MatthewWatson you're talking about first or second one?
    – SeM
    Nov 30 at 11:04






  • 2




    @SeM Both, because neither of those answers talk about overriding properties.
    – Matthew Watson
    Nov 30 at 11:06






  • 2




    I think it's related to that and virtual member access in constructor, no? Though it's clear if you look at how it's compiled: both classes get their own private backing field. The one in the child class gets returned. sharplab.io/…
    – pinkfloydx33
    Nov 30 at 11:07






  • 2




    For bonus points, add Console.WriteLine(ReadOnly); in the base constructor, after assigning to the property.
    – Lasse Vågsæther Karlsen
    Nov 30 at 11:34













up vote
38
down vote

favorite
2









up vote
38
down vote

favorite
2






2





I tried the following example:



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
}
}


When I create an instance of Test, I see that ReadOnly stays null. But why?
I really do not get the hang of it, could somebody please explain to me why this happens? At least I would expect and error, that a read-only property cannot be set outside of the owning class.










share|improve this question















I tried the following example:



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
}
}


When I create an instance of Test, I see that ReadOnly stays null. But why?
I really do not get the hang of it, could somebody please explain to me why this happens? At least I would expect and error, that a read-only property cannot be set outside of the owning class.







c# automatic-properties






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 30 at 11:07

























asked Nov 30 at 10:49









apfelstrudel24

19316




19316








  • 1




    @SeM It's not really a duplicate, since this question is about the affect that overriding the string property is having.
    – Matthew Watson
    Nov 30 at 11:04










  • @MatthewWatson you're talking about first or second one?
    – SeM
    Nov 30 at 11:04






  • 2




    @SeM Both, because neither of those answers talk about overriding properties.
    – Matthew Watson
    Nov 30 at 11:06






  • 2




    I think it's related to that and virtual member access in constructor, no? Though it's clear if you look at how it's compiled: both classes get their own private backing field. The one in the child class gets returned. sharplab.io/…
    – pinkfloydx33
    Nov 30 at 11:07






  • 2




    For bonus points, add Console.WriteLine(ReadOnly); in the base constructor, after assigning to the property.
    – Lasse Vågsæther Karlsen
    Nov 30 at 11:34














  • 1




    @SeM It's not really a duplicate, since this question is about the affect that overriding the string property is having.
    – Matthew Watson
    Nov 30 at 11:04










  • @MatthewWatson you're talking about first or second one?
    – SeM
    Nov 30 at 11:04






  • 2




    @SeM Both, because neither of those answers talk about overriding properties.
    – Matthew Watson
    Nov 30 at 11:06






  • 2




    I think it's related to that and virtual member access in constructor, no? Though it's clear if you look at how it's compiled: both classes get their own private backing field. The one in the child class gets returned. sharplab.io/…
    – pinkfloydx33
    Nov 30 at 11:07






  • 2




    For bonus points, add Console.WriteLine(ReadOnly); in the base constructor, after assigning to the property.
    – Lasse Vågsæther Karlsen
    Nov 30 at 11:34








1




1




@SeM It's not really a duplicate, since this question is about the affect that overriding the string property is having.
– Matthew Watson
Nov 30 at 11:04




@SeM It's not really a duplicate, since this question is about the affect that overriding the string property is having.
– Matthew Watson
Nov 30 at 11:04












@MatthewWatson you're talking about first or second one?
– SeM
Nov 30 at 11:04




@MatthewWatson you're talking about first or second one?
– SeM
Nov 30 at 11:04




2




2




@SeM Both, because neither of those answers talk about overriding properties.
– Matthew Watson
Nov 30 at 11:06




@SeM Both, because neither of those answers talk about overriding properties.
– Matthew Watson
Nov 30 at 11:06




2




2




I think it's related to that and virtual member access in constructor, no? Though it's clear if you look at how it's compiled: both classes get their own private backing field. The one in the child class gets returned. sharplab.io/…
– pinkfloydx33
Nov 30 at 11:07




I think it's related to that and virtual member access in constructor, no? Though it's clear if you look at how it's compiled: both classes get their own private backing field. The one in the child class gets returned. sharplab.io/…
– pinkfloydx33
Nov 30 at 11:07




2




2




For bonus points, add Console.WriteLine(ReadOnly); in the base constructor, after assigning to the property.
– Lasse Vågsæther Karlsen
Nov 30 at 11:34




For bonus points, add Console.WriteLine(ReadOnly); in the base constructor, after assigning to the property.
– Lasse Vågsæther Karlsen
Nov 30 at 11:34












2 Answers
2






active

oldest

votes

















up vote
36
down vote



accepted










The compiler treats this as below; basically, the code in the constructor writes to the original backing field, in TestBase. It seems that yours is not a supported scenario, but... I do wonder whether the language team have considered this case.



BTW: if you ever want to see what the compiler does with code: 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
}
}
}





share|improve this answer

















  • 2




    And before anyone complains that "who cares, you shouldn't be doing this anyway as it gives you nothing", then consider that you can add attributes to the overridden property in the descendant, which will be combined with attributes on the property in the base class. So it does give you something, and although it's probably not a feature many uses, it might be important in serialization scenarios.
    – Lasse Vågsæther Karlsen
    Nov 30 at 11:24












  • @LasseVågsætherKarlsen I really want to send up the "Jared Signal" - kinda like the Bat Signal, but... geekier. Should I?
    – Marc Gravell
    Nov 30 at 11:26






  • 1




    Definitely, personally I feel that using virtual members in the constructor is the wrong thing to do, but the compiler doesn't explicitly warn about it and does in fact work, with all the usual documented warnings about what might break and why, so here I did actually expect the property to be assigned though I fully understand why not. Perhaps this particular scenario needs to be explicitly handled, either with a warning or actual support.
    – Lasse Vågsæther Karlsen
    Nov 30 at 11:27










  • Though I feel that adding full support for this smells like a can of worms, but yes, I believe in knowledge and willfull decisions, so light the floodlight and let the team decide :)
    – Lasse Vågsæther Karlsen
    Nov 30 at 11:27






  • 3




    There is no sane way to fix this, other than possibly adding the warning. Just try to add a Console.WriteLine(ReadOnly); in the base constructor, after assigning to ReadOnly and you'll see a different symptom, it will call the descendant getter, of the property we know hasn't been assigned, and thus try to print null. The only sane fix here, if anything, would be that compiling the descendant class should warn that you actually have two distinct property implementations.
    – Lasse Vågsæther Karlsen
    Nov 30 at 11:34




















up vote
17
down vote













The easiest way to explain this is to consider what code the compiler is generating to implement this.



The base class is equivalent to this:



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

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

readonly string _testBaseReadOnly;
}


The derived class is equivalent to this:



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

readonly string _testReadOnly;
}


The important thing to note here is that the derived class has its OWN BACKING FIELD for ReadOnly - it does NOT re-use the one from the base class.



Having realised that, it should be apparent why the overridden property is null.



It's because the derived class has its own backing field for ReadOnly, and its constructor is not initialising that backing field.



Incidentally, if you're using Resharper it will actually warn you that you're not setting ReadOnly in the derived class:



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





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53556028%2fwhy-does-an-overridden-get-only-property-stay-null-when-set-in-base-class-constr%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    36
    down vote



    accepted










    The compiler treats this as below; basically, the code in the constructor writes to the original backing field, in TestBase. It seems that yours is not a supported scenario, but... I do wonder whether the language team have considered this case.



    BTW: if you ever want to see what the compiler does with code: 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
    }
    }
    }





    share|improve this answer

















    • 2




      And before anyone complains that "who cares, you shouldn't be doing this anyway as it gives you nothing", then consider that you can add attributes to the overridden property in the descendant, which will be combined with attributes on the property in the base class. So it does give you something, and although it's probably not a feature many uses, it might be important in serialization scenarios.
      – Lasse Vågsæther Karlsen
      Nov 30 at 11:24












    • @LasseVågsætherKarlsen I really want to send up the "Jared Signal" - kinda like the Bat Signal, but... geekier. Should I?
      – Marc Gravell
      Nov 30 at 11:26






    • 1




      Definitely, personally I feel that using virtual members in the constructor is the wrong thing to do, but the compiler doesn't explicitly warn about it and does in fact work, with all the usual documented warnings about what might break and why, so here I did actually expect the property to be assigned though I fully understand why not. Perhaps this particular scenario needs to be explicitly handled, either with a warning or actual support.
      – Lasse Vågsæther Karlsen
      Nov 30 at 11:27










    • Though I feel that adding full support for this smells like a can of worms, but yes, I believe in knowledge and willfull decisions, so light the floodlight and let the team decide :)
      – Lasse Vågsæther Karlsen
      Nov 30 at 11:27






    • 3




      There is no sane way to fix this, other than possibly adding the warning. Just try to add a Console.WriteLine(ReadOnly); in the base constructor, after assigning to ReadOnly and you'll see a different symptom, it will call the descendant getter, of the property we know hasn't been assigned, and thus try to print null. The only sane fix here, if anything, would be that compiling the descendant class should warn that you actually have two distinct property implementations.
      – Lasse Vågsæther Karlsen
      Nov 30 at 11:34

















    up vote
    36
    down vote



    accepted










    The compiler treats this as below; basically, the code in the constructor writes to the original backing field, in TestBase. It seems that yours is not a supported scenario, but... I do wonder whether the language team have considered this case.



    BTW: if you ever want to see what the compiler does with code: 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
    }
    }
    }





    share|improve this answer

















    • 2




      And before anyone complains that "who cares, you shouldn't be doing this anyway as it gives you nothing", then consider that you can add attributes to the overridden property in the descendant, which will be combined with attributes on the property in the base class. So it does give you something, and although it's probably not a feature many uses, it might be important in serialization scenarios.
      – Lasse Vågsæther Karlsen
      Nov 30 at 11:24












    • @LasseVågsætherKarlsen I really want to send up the "Jared Signal" - kinda like the Bat Signal, but... geekier. Should I?
      – Marc Gravell
      Nov 30 at 11:26






    • 1




      Definitely, personally I feel that using virtual members in the constructor is the wrong thing to do, but the compiler doesn't explicitly warn about it and does in fact work, with all the usual documented warnings about what might break and why, so here I did actually expect the property to be assigned though I fully understand why not. Perhaps this particular scenario needs to be explicitly handled, either with a warning or actual support.
      – Lasse Vågsæther Karlsen
      Nov 30 at 11:27










    • Though I feel that adding full support for this smells like a can of worms, but yes, I believe in knowledge and willfull decisions, so light the floodlight and let the team decide :)
      – Lasse Vågsæther Karlsen
      Nov 30 at 11:27






    • 3




      There is no sane way to fix this, other than possibly adding the warning. Just try to add a Console.WriteLine(ReadOnly); in the base constructor, after assigning to ReadOnly and you'll see a different symptom, it will call the descendant getter, of the property we know hasn't been assigned, and thus try to print null. The only sane fix here, if anything, would be that compiling the descendant class should warn that you actually have two distinct property implementations.
      – Lasse Vågsæther Karlsen
      Nov 30 at 11:34















    up vote
    36
    down vote



    accepted







    up vote
    36
    down vote



    accepted






    The compiler treats this as below; basically, the code in the constructor writes to the original backing field, in TestBase. It seems that yours is not a supported scenario, but... I do wonder whether the language team have considered this case.



    BTW: if you ever want to see what the compiler does with code: 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
    }
    }
    }





    share|improve this answer












    The compiler treats this as below; basically, the code in the constructor writes to the original backing field, in TestBase. It seems that yours is not a supported scenario, but... I do wonder whether the language team have considered this case.



    BTW: if you ever want to see what the compiler does with code: 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
    }
    }
    }






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 30 at 11:18









    Marc Gravell

    773k19021232538




    773k19021232538








    • 2




      And before anyone complains that "who cares, you shouldn't be doing this anyway as it gives you nothing", then consider that you can add attributes to the overridden property in the descendant, which will be combined with attributes on the property in the base class. So it does give you something, and although it's probably not a feature many uses, it might be important in serialization scenarios.
      – Lasse Vågsæther Karlsen
      Nov 30 at 11:24












    • @LasseVågsætherKarlsen I really want to send up the "Jared Signal" - kinda like the Bat Signal, but... geekier. Should I?
      – Marc Gravell
      Nov 30 at 11:26






    • 1




      Definitely, personally I feel that using virtual members in the constructor is the wrong thing to do, but the compiler doesn't explicitly warn about it and does in fact work, with all the usual documented warnings about what might break and why, so here I did actually expect the property to be assigned though I fully understand why not. Perhaps this particular scenario needs to be explicitly handled, either with a warning or actual support.
      – Lasse Vågsæther Karlsen
      Nov 30 at 11:27










    • Though I feel that adding full support for this smells like a can of worms, but yes, I believe in knowledge and willfull decisions, so light the floodlight and let the team decide :)
      – Lasse Vågsæther Karlsen
      Nov 30 at 11:27






    • 3




      There is no sane way to fix this, other than possibly adding the warning. Just try to add a Console.WriteLine(ReadOnly); in the base constructor, after assigning to ReadOnly and you'll see a different symptom, it will call the descendant getter, of the property we know hasn't been assigned, and thus try to print null. The only sane fix here, if anything, would be that compiling the descendant class should warn that you actually have two distinct property implementations.
      – Lasse Vågsæther Karlsen
      Nov 30 at 11:34
















    • 2




      And before anyone complains that "who cares, you shouldn't be doing this anyway as it gives you nothing", then consider that you can add attributes to the overridden property in the descendant, which will be combined with attributes on the property in the base class. So it does give you something, and although it's probably not a feature many uses, it might be important in serialization scenarios.
      – Lasse Vågsæther Karlsen
      Nov 30 at 11:24












    • @LasseVågsætherKarlsen I really want to send up the "Jared Signal" - kinda like the Bat Signal, but... geekier. Should I?
      – Marc Gravell
      Nov 30 at 11:26






    • 1




      Definitely, personally I feel that using virtual members in the constructor is the wrong thing to do, but the compiler doesn't explicitly warn about it and does in fact work, with all the usual documented warnings about what might break and why, so here I did actually expect the property to be assigned though I fully understand why not. Perhaps this particular scenario needs to be explicitly handled, either with a warning or actual support.
      – Lasse Vågsæther Karlsen
      Nov 30 at 11:27










    • Though I feel that adding full support for this smells like a can of worms, but yes, I believe in knowledge and willfull decisions, so light the floodlight and let the team decide :)
      – Lasse Vågsæther Karlsen
      Nov 30 at 11:27






    • 3




      There is no sane way to fix this, other than possibly adding the warning. Just try to add a Console.WriteLine(ReadOnly); in the base constructor, after assigning to ReadOnly and you'll see a different symptom, it will call the descendant getter, of the property we know hasn't been assigned, and thus try to print null. The only sane fix here, if anything, would be that compiling the descendant class should warn that you actually have two distinct property implementations.
      – Lasse Vågsæther Karlsen
      Nov 30 at 11:34










    2




    2




    And before anyone complains that "who cares, you shouldn't be doing this anyway as it gives you nothing", then consider that you can add attributes to the overridden property in the descendant, which will be combined with attributes on the property in the base class. So it does give you something, and although it's probably not a feature many uses, it might be important in serialization scenarios.
    – Lasse Vågsæther Karlsen
    Nov 30 at 11:24






    And before anyone complains that "who cares, you shouldn't be doing this anyway as it gives you nothing", then consider that you can add attributes to the overridden property in the descendant, which will be combined with attributes on the property in the base class. So it does give you something, and although it's probably not a feature many uses, it might be important in serialization scenarios.
    – Lasse Vågsæther Karlsen
    Nov 30 at 11:24














    @LasseVågsætherKarlsen I really want to send up the "Jared Signal" - kinda like the Bat Signal, but... geekier. Should I?
    – Marc Gravell
    Nov 30 at 11:26




    @LasseVågsætherKarlsen I really want to send up the "Jared Signal" - kinda like the Bat Signal, but... geekier. Should I?
    – Marc Gravell
    Nov 30 at 11:26




    1




    1




    Definitely, personally I feel that using virtual members in the constructor is the wrong thing to do, but the compiler doesn't explicitly warn about it and does in fact work, with all the usual documented warnings about what might break and why, so here I did actually expect the property to be assigned though I fully understand why not. Perhaps this particular scenario needs to be explicitly handled, either with a warning or actual support.
    – Lasse Vågsæther Karlsen
    Nov 30 at 11:27




    Definitely, personally I feel that using virtual members in the constructor is the wrong thing to do, but the compiler doesn't explicitly warn about it and does in fact work, with all the usual documented warnings about what might break and why, so here I did actually expect the property to be assigned though I fully understand why not. Perhaps this particular scenario needs to be explicitly handled, either with a warning or actual support.
    – Lasse Vågsæther Karlsen
    Nov 30 at 11:27












    Though I feel that adding full support for this smells like a can of worms, but yes, I believe in knowledge and willfull decisions, so light the floodlight and let the team decide :)
    – Lasse Vågsæther Karlsen
    Nov 30 at 11:27




    Though I feel that adding full support for this smells like a can of worms, but yes, I believe in knowledge and willfull decisions, so light the floodlight and let the team decide :)
    – Lasse Vågsæther Karlsen
    Nov 30 at 11:27




    3




    3




    There is no sane way to fix this, other than possibly adding the warning. Just try to add a Console.WriteLine(ReadOnly); in the base constructor, after assigning to ReadOnly and you'll see a different symptom, it will call the descendant getter, of the property we know hasn't been assigned, and thus try to print null. The only sane fix here, if anything, would be that compiling the descendant class should warn that you actually have two distinct property implementations.
    – Lasse Vågsæther Karlsen
    Nov 30 at 11:34






    There is no sane way to fix this, other than possibly adding the warning. Just try to add a Console.WriteLine(ReadOnly); in the base constructor, after assigning to ReadOnly and you'll see a different symptom, it will call the descendant getter, of the property we know hasn't been assigned, and thus try to print null. The only sane fix here, if anything, would be that compiling the descendant class should warn that you actually have two distinct property implementations.
    – Lasse Vågsæther Karlsen
    Nov 30 at 11:34














    up vote
    17
    down vote













    The easiest way to explain this is to consider what code the compiler is generating to implement this.



    The base class is equivalent to this:



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

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

    readonly string _testBaseReadOnly;
    }


    The derived class is equivalent to this:



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

    readonly string _testReadOnly;
    }


    The important thing to note here is that the derived class has its OWN BACKING FIELD for ReadOnly - it does NOT re-use the one from the base class.



    Having realised that, it should be apparent why the overridden property is null.



    It's because the derived class has its own backing field for ReadOnly, and its constructor is not initialising that backing field.



    Incidentally, if you're using Resharper it will actually warn you that you're not setting ReadOnly in the derived class:



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





    share|improve this answer



























      up vote
      17
      down vote













      The easiest way to explain this is to consider what code the compiler is generating to implement this.



      The base class is equivalent to this:



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

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

      readonly string _testBaseReadOnly;
      }


      The derived class is equivalent to this:



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

      readonly string _testReadOnly;
      }


      The important thing to note here is that the derived class has its OWN BACKING FIELD for ReadOnly - it does NOT re-use the one from the base class.



      Having realised that, it should be apparent why the overridden property is null.



      It's because the derived class has its own backing field for ReadOnly, and its constructor is not initialising that backing field.



      Incidentally, if you're using Resharper it will actually warn you that you're not setting ReadOnly in the derived class:



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





      share|improve this answer

























        up vote
        17
        down vote










        up vote
        17
        down vote









        The easiest way to explain this is to consider what code the compiler is generating to implement this.



        The base class is equivalent to this:



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

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

        readonly string _testBaseReadOnly;
        }


        The derived class is equivalent to this:



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

        readonly string _testReadOnly;
        }


        The important thing to note here is that the derived class has its OWN BACKING FIELD for ReadOnly - it does NOT re-use the one from the base class.



        Having realised that, it should be apparent why the overridden property is null.



        It's because the derived class has its own backing field for ReadOnly, and its constructor is not initialising that backing field.



        Incidentally, if you're using Resharper it will actually warn you that you're not setting ReadOnly in the derived class:



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





        share|improve this answer














        The easiest way to explain this is to consider what code the compiler is generating to implement this.



        The base class is equivalent to this:



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

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

        readonly string _testBaseReadOnly;
        }


        The derived class is equivalent to this:



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

        readonly string _testReadOnly;
        }


        The important thing to note here is that the derived class has its OWN BACKING FIELD for ReadOnly - it does NOT re-use the one from the base class.



        Having realised that, it should be apparent why the overridden property is null.



        It's because the derived class has its own backing field for ReadOnly, and its constructor is not initialising that backing field.



        Incidentally, if you're using Resharper it will actually warn you that you're not setting ReadOnly in the derived class:



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






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 30 at 11:23

























        answered Nov 30 at 11:00









        Matthew Watson

        72k691176




        72k691176






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53556028%2fwhy-does-an-overridden-get-only-property-stay-null-when-set-in-base-class-constr%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

            ComboBox Display Member on multiple fields

            Is it possible to collect Nectar points via Trainline?