0

I have a very simple Color class implemented below:

using System;
namespace HelloWorld
{
    internal class Color
    {
        private byte red;
        private byte green;
        private byte blue;
        private byte alpha;

        public Color(byte red, byte green, byte blue, byte alpha)
        {
            this.red = red;
            this.green = green;
            this.blue = blue;
            this.alpha = alpha;
        }

        public Color(byte red, byte green, byte blue)
        {
            this.red = red;
            this.green = green;
            this.blue = blue;
            this.alpha = 255;
        }

        public byte Red { get; set; }
        public byte Green { get; set; }
        public byte Blue { get; set; }
        public byte Alpha { get; set; }



        public float GreyScale
        {
            get
            {
                return (red + green + blue) / 3.0F;
            }
        }
    }
}

I have a property called GreyScale which simply returns the average of the red, green and blue fields as a float. However, when I execute the following code, once the GreyScale property is called the first time, subsequent changes to writeable class members doesn't change the value of GreyScale once it's called again.

Color color = new Color(255, 255, 255, 255);
Console.WriteLine($"{color.GreyScale}"); // prints 255 as expected
color.Red = 197;
color.Green = 197;
color.Blue = 197;
Console.WriteLine(%"{color.GreyScale}");// should print 197. Prints 255.
Mutating Algorithm
  • 2,604
  • 2
  • 29
  • 66
  • @LewsTherin: If that were true, wouldn't it throw on `color.Red = 197`? – Robert Harvey Dec 14 '18 at 19:35
  • 2
    @LewsTherin I think you might need to revisit your understanding of how properties work. Its syntactic sugar for a method, it can certainly read the class's *current* state. Properties in and of themselves have no state – BradleyDotNET Dec 14 '18 at 19:35
  • @LewsTherin: Not the real problem. See answers below. – Robert Harvey Dec 14 '18 at 19:36
  • I totally missed the private backing fields are the ones being used to calculate the `GreyScale`. Case-sensitive C# fools me again :) – Lews Therin Dec 14 '18 at 19:37

2 Answers2

5

You just have a misunderstanding of a C# auto property {get; set;} which is just syntactic sugar, the compiler creates the private backing variables for the public properties with getters and setters. You do not need to create the private byte fields and thus you will not use them in your code.

using System;
namespace HelloWorld
{
    internal class Color
    {

        public Color(byte red, byte green, byte blue, byte alpha)
        {
            this.Red= red;
            this.Green = green;
            this.Blue = blue;
            this.Alpha= alpha;
        }

        public Color(byte red, byte green, byte blue)
        {
            this.Red= red;
            this.Green = green;
            this.Blue = blue;
            this.Alpha = 255;
        }

        public byte Red { get; set; }
        public byte Green { get; set; }
        public byte Blue { get; set; }
        public byte Alpha { get; set; }



        public float GreyScale
        {
            get
            {
                return (this.Red + this.Green + this.Blue) / 3.0F;
            }
        }
    }
}
Brian Ogden
  • 18,439
  • 10
  • 97
  • 176
1

When you set the properties Red, Green and Blue, the fields red, green and blue are not being updated.

If GreyScale were implemented as return (Red + Green + Blue), it would work, but only after setting those properties.

I think you probably want to implement the getters and setters for Red, Green and Blue to read and write to the backing fields.

Jay
  • 56,361
  • 10
  • 99
  • 123