2

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

  }


  • 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
  • That'd work in C# 6. In <6 an auto-property cannot declare only a get accessor. - Chris
  • @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
  • it's not only C#6 and it's not marked C#6 - AnthonyLambert
  • @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. In fact, I've been using VS2015 for production code, targeting 4.5 for a while now - Panagiotis Kanavos

4 답변


8

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


3

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


  • Or compile with VS 2015. The OP's examples are from C# 6 - Panagiotis Kanavos
  • This is not obious to me, wher do you got this information from? - HimBromBeere
  • It's the C# 6 syntax. I've been using this for months. The second example, {get;}="green" is an auto-property initializer - Panagiotis Kanavos

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

}


  • The OP's syntax is valid for C#6. - Panagiotis Kanavos
  • @PanagiotisKanavos But as OPs code does NOT work (for any reason he did not mentioned until now), he may not use C#6. - HimBromBeere
  • Visual Studio 2015 uses C# 6. The code is C# 6. That the OP is using the wrong compiler is a different question. - Panagiotis Kanavos
  • @PanagiotisKanavos The code MAY be C#6, or there´s actually a typeo or something similar in it which would cause the OPs error. We do not know as OP does not tell. - HimBromBeere
  • @HimBromBeere I've added a tag - I'm using the wrong compiler. So maybe this isn't even a valid question. I do appreciate all the help though as it is all quite new to me. - whytheq

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


  • Your second suggestion won't compile - you probably meant get; private set; - dcastro
  • { get { return colour; } private set; } won't work, probably doesn't even compile. Did you mean {get; private set;} ? - Panagiotis Kanavos
  • Thanks for the feedback, have fixed it. - Dr Rob Lang

Linked


Related

Latest