5

Why doesn't this run:

  class Program
  {
    static void Main(string[] args)
    {
      Apple a = new Apple("green");
    }
  }

  class Apple
  {

    public string Colour{ get; }

    public Apple(string colour)
    {
      this.Colour = colour;
    }

  }
whytheq
  • 34,466
  • 65
  • 172
  • 267
  • 2
    you should define it in this way public string Colour {get; private set;} or you can define a private member _color and you left the get to return that value and in the constructor you fill _color – Monah Jul 23 '15 at 09:51
  • @HimBromBeere so I need to use `public string Colour{ get; } = "green"` ? – whytheq Jul 23 '15 at 09:51
  • 8
    That'd work in C# 6. In <6 an auto-property cannot declare only a get accessor. – Chris Jul 23 '15 at 09:52
  • 2
    @whytheq which version of Visual Studio are you using to compile this? In 2015 both your code and `Colour{ get; } = "green"` would work. In previous versions none of them would, you'd have to declare a private setter, `Colour {get;private set;}` – Panagiotis Kanavos Jul 23 '15 at 09:57
  • @AnthonyLambert not a duplicate at all, it's a C# 6 question and the linked question is from 2009 – Panagiotis Kanavos Jul 23 '15 at 09:59
  • 1
    it's not only C#6 and it's not marked C#6 – AnthonyLambert Jul 23 '15 at 10:00
  • @whytheq How are you trying to compile this? Which version of Visual Studio are you using? Are you perhaps trying to compile from the command line? – Panagiotis Kanavos Jul 23 '15 at 10:19
  • @PanagiotisKanavos it is ok - I can use the old way. I have 4.5 and not really ready yet for 4.6. I think this question is ok though as it highlights someone being silly trying to run a 4.6 feature in a 4.5 app – whytheq Jul 23 '15 at 10:31
  • 1
    @whytheq you don't need 4.6 to run this, you can target 4.5 without problem. The language and the runtime are two different things as [discussed here](http://stackoverflow.com/questions/31570654/why-does-net-4-6-specific-code-compile-when-targeting-older-versions-of-the-fra). In fact, I've been using VS2015 for production code, targeting 4.5 for a while now – Panagiotis Kanavos Jul 23 '15 at 10:33
  • @PanagiotisKanavos let me add a couple of more specific tags. Suspect more down-votes are on their way but this is all pretty new technology to me – whytheq Jul 23 '15 at 10:35
  • @PanagiotisKanavos I don't know how to run it : what do I change in my current set up to run it. I will need to install the latest framework on the machine running the application at least? But the property setting of the project can stay as 4.5? – whytheq Jul 23 '15 at 10:53
  • You can't use C#6 with VS 2012. You can install VS 2015 side-by-side though and Community Edition is free and equivalent to the old Professional. – Panagiotis Kanavos Jul 23 '15 at 11:06
  • it would of helped if he originally tagged/mentioned c#6 or VS2015 when he asked the question, it just looked like he implemented his property incorrectly to those of us still on prior versions. – AnthonyLambert Jul 23 '15 at 12:32
  • @AnthonyLambert apologies for any confusion caused. I try to help answering `mdx` questions - you would not believe the vagueness of questions asked concerning that language! – whytheq Jul 23 '15 at 13:34

4 Answers4

10

Your code is valid for C# 6, which comes with Visual Studio 2015. It is not valid for previous versions of the language or Visual Studio. Technically, you can install an old pre-release version of Roslyn in VS 2013 but it isn't worth the trouble now that VS 2015 was released.

For this problem to occur, either you are using the wrong version of Visual Studio to compile C# 6 code, or you are trying to compile your code from the command line using the wrong development environment -ie, your PATH points to the old compiler. Perhaps you opened the 'Developer Command Prompt for 2013' instead of 2015?

You should either compile your code using Visual Studio 2015, or ensure your path variable points to the latest compiler.

If you have to use Visual Studio 2013 or older, you'll have to change your code to use the older syntax, eg:

public readonly string _colour;

public string Colour { get {return _colour;}}

public Apple(string colour)
{
    _colour=colour;
}

or

public string Colour {get; private set;}

public Apple(string colour)
{
    Colour=colour;
}

Note that the second option isn't truly read-only, other members of the class can still modify the property

NOTE

You can use Visual Studio 2015 to target .NET 4.5. The language and the runtime are two different things. The real requirement is that the compiler must match the language version

Community
  • 1
  • 1
Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
4

Either add a private setter to your property:

public string Colour{ get; private set;}

Or add a readonly backing-field:

private string _colour;
public string Colour{ get return this._colour; }

public Apple(string colour)
{
  this._colour = colour;
}
MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111
2

I think what you're looking for is this, which keeps your internal variable protected by only exposing a GET to the outside world. For extra safety you could mark _colour as readonly so that it can't be changed within the class itself either (after instantiation), but I think that's overkill. What if your apple gets old and needs to turn brown ?!

class Program
{
    static void Main(string[] args)
    {
        Apple a = new Apple("green");
    }
}

class Apple
{
    private string _colour;
    public string Colour
    {
        get
        {
            return _colour;
        }
    }

    public Apple(string colour)
    {
        this._colour = colour;
    }

}
Oliver Gray
  • 874
  • 6
  • 17
1

You have a couple of options here:

// Make the string read only after the constructor has set it
private readonly string colour
public string Colour { get { return colour; } }

public Apple(string colour)
{
  this.colour = colour;
}


// Make the string only readonly from outside but editing from within the class
public string Colour { get; private set; }

public Apple(string colour)
{
  this.Colour= colour;
}
Dr Rob Lang
  • 6,659
  • 5
  • 40
  • 60