2

To my surprise, the following code builds and runs fine:

private abstract class MyParent
{
    public abstract bool MyBool { get; }
}

private class MyChild : MyParent
{
    public override bool MyBool { get; } //no body declared
}

[TestMethod]
public void MyTestMethod()
{
    var mc = new MyChild();
    Assert.IsFalse(mc.MyBool);
}

I don't get any warnings either. The test even passes. I wouldn't expect this to compile because the MyChild class doesn't declare a body for the overridden MyBool getter. I tried marking the MyChild class sealed, but it still compiled. My first question is simply, why is the MyChild class not required to provide a body for the MyBool getter?

I found that I had a problem like this in my code because my build server reported a compiler error that said:

'MyChild.MyBool.get' must declare a body because it is not marked abstract or extern. Automatically implemented properties must define both get and set accessors.

The build server must be using some settings that prevented this same code from compiling. My second question is: what settings can I check to ensure that the compiler gives me this warning when I try to compile this code?

user2023861
  • 6,808
  • 6
  • 42
  • 64
  • 3
    It has an implicit getter. This is entirely correct and recommended property syntax for simple property getters. See here on [Auto-Implemented Properties](https://msdn.microsoft.com/en-us/library/bb384054.aspx). You can still define it as a `private get;`, if you don't wish it to be overridden. In the example provided, the sub class simply implements the same getter as its base class. No problem there. – ManoDestra Jun 13 '16 at 20:29
  • I don't think you can get an exception on this – techspider Jun 13 '16 at 20:29
  • *To my surprise, the following code builds and runs fine:* Yeah something is definitely not right if that's true. [Compiler Error CS0840](https://msdn.microsoft.com/en-us/library/bb397743.aspx) says it shouldn't. I would try and clean and build. Or look at the assembly with Ildasm.exe to take a look at what you're actually running – Conrad Frix Jun 13 '16 at 20:42
  • 1
    The documentation is wrong @ConradFrix – Patrick Hofman Jun 13 '16 at 20:44
  • @ConradFrix Try that in a VS2015 Roslyn compiler. Also try adding `public Test() { myProp = 2; }` for fun. – Patrick Hofman Jun 13 '16 at 20:46
  • @ConradFrix Also read [here](http://stackoverflow.com/a/34060294/993547). You are not the only one confused. – Patrick Hofman Jun 13 '16 at 20:47
  • @PatrickHofman I guess I fell off the microsoft treadmill. Incidentally I left feedback on the CS0840 error. Maybe they'll fix it. – Conrad Frix Jun 13 '16 at 21:04

1 Answers1

3

I wouldn't expect this to compile because the MyChild class doesn't declare a body for the overridden MyBool getter.

That is because it is perfectly fine. The MyBool property has an (implicit) setter, but that is only available to the constructor. This is a new feature to the C# 6 compiler, so your build server needs the same version of the compiler to make this work.

There is no need to throw an exception, or anything like that. If you want a set to be declared, just make sure to add it to the property definition in the base class.

Patrick Hofman
  • 143,714
  • 19
  • 222
  • 294
  • Oh, yes. That is useful to add :) – Patrick Hofman Jun 13 '16 at 20:33
  • Do you know what would have cause me to get a compiler error when compiling on a build server? It's possible that the build server we use us using an older compiler, but I would guess that auto-implemented properties would've been around longer. – user2023861 Jun 13 '16 at 20:34
  • This feature has been around for a while http://stackoverflow.com/questions/6001917/what-are-automatic-properties-in-c-sharp-and-what-is-their-purpose – ManoDestra Jun 13 '16 at 20:34
  • A year or so, it was shipped with VS 2015. @ManoDestra – Patrick Hofman Jun 13 '16 at 20:35
  • @user2023861 Yes, you run an old version of the compiler, see the update. – Patrick Hofman Jun 13 '16 at 20:35
  • That is an entirely different feature @ManoDestra – Patrick Hofman Jun 13 '16 at 20:37
  • @ManoDestra Auto-implemented properties with a setter have been around for years. Auto-implemented properties with only a getter haven't. –  Jun 13 '16 at 20:38
  • @ManoDestra You're confusing auto-properties with implicit setters. Until VS 2015/C#6 an auto-property with no setter would not make sense. – Glorin Oakenfoot Jun 13 '16 at 20:38
  • 2
    That was it. I switched the compiler on my desktop from C# 6 to C# 5 and now I'm getting this error message: `Feature 'readonly automatically implemented properties' is not available in C# 5. Please use language version 6 or greater.` Thanks everyone. – user2023861 Jun 13 '16 at 20:38
  • Ah, apologies for the confusion. Crossed wires. – ManoDestra Jun 13 '16 at 20:38
  • 2
    Worth adding, perhaps: if the build server is not using Visual Studio to perform the build (but instead using msbuild or something else), then that might explain why the old compiler is getting used even if all software is up to date. In that case, instead of tweaking to make the code fail to compile, the Microsoft.Net.Compilers NuGet package can be installed to force a C# 6 compiler to be used everywhere, even on a build server that might otherwise not have it. –  Jun 13 '16 at 20:39