1

I have the following class with auto properties:

class Coordinates
{
    public Coordinates(int x, int y)
    {
        X = x * 10;
        Y = y * 10;
    }

    public int X { get; set; }

    public int Y { get; set; }
}

As you can see from the constructor I need the value to be multiplied by 10. Is there anyway to do it without removing autoproperties?

I tried the following not thinking that it causes recursion and then everything goes fubar

public int X { get {return X;} set{ X *= 10;} }

I would like to assign values to X and Y multiplied by 10.

Coordinates coords = new Coordinates(5, 6); // coords.X = 50 coords.Y = 60
coords.X = 7; // this gives 7 to X but I would like it to be 70.
Orel Eraki
  • 11,940
  • 3
  • 28
  • 36
Oiproks
  • 764
  • 1
  • 9
  • 34
  • 3
    I don´t get what you mean by "Is there anyway to do it without removing autoproperties?" You don´t remove anything by setting an initial value within the constructor. – MakePeaceGreatAgain Sep 03 '19 at 10:40
  • 3
    What is the problem? Your *original* code works just fine. Do you want to store a *different* value in the setter perhaps? – Panagiotis Kanavos Sep 03 '19 at 10:42
  • "As you can see from the constructor I need the value to be multiplied by 10." On construction? Or every time you set? It's unclear what you're trying to achieve - please clarify. – Jon Skeet Sep 03 '19 at 10:46
  • Just edited. I hope it clarifies – Oiproks Sep 03 '19 at 10:48
  • try, private int x; public int X { get {return x;} set{ x = value * 10;} } – DomCR Sep 03 '19 at 10:49
  • "this gives 7 to X but I would like it to be 70." This is *very* counterintuitive. When you assign 7, you usually want 7, not 70. – MakePeaceGreatAgain Sep 03 '19 at 10:49
  • you could setup members to store the value, and use the get and set to make the operation. – DomCR Sep 03 '19 at 10:50
  • Why do you not try to multiply by `10` before passing to constructor? – SᴇM Sep 03 '19 at 10:50
  • @Dom93 that will cause recursion, and then a StackOverflow XD – Oiproks Sep 03 '19 at 10:56
  • I am not happy with what you try to do. Setting a Value should not have the side effect of multiplying it. The class name is Coordinates. So one would expect to be able to store coordinates in it. But instead it manipulates the properties. That coding Style is unsexy :) – Daniel Schmid Sep 03 '19 at 10:56
  • @HimBromBeere it is internal for matrix calculation. It is needed. – Oiproks Sep 03 '19 at 10:57
  • the comment I posted is exactly the same as the answer, but I couldn't post it because is on hold – DomCR Sep 03 '19 at 10:58
  • I was about to answer the question, but they marked it as OnHold which prevents me of giving you a full detail. – Orel Eraki Sep 03 '19 at 11:04

2 Answers2

5

In order to make setter working like that, you'll need to use backing field:

class Coordinates
{
    public Coordinates(int x, int y)
    {
        X = x;
        Y = y;
    }

    private int _x;
    public int X
    {
        get { return _x; }
        set { _x = value * 10; }
    }

    private int _y;
    public int Y
    {
        get { return _y; }
        set { _y = value * 10; }
    }
}

Given your example:

Coordinates coords = new Coordinates(5, 6); // coords.X = 50 coords.Y = 60
coords.X = 7; // this gives 70

However, I don't recommend you having such setter because it could lead to confusion. It's better to have a dedicated method which will do such multiplication. In the end, your code will be more descriptive and intuitive.

Darjan Bogdan
  • 3,780
  • 1
  • 22
  • 31
  • 1
    Ok. This is what I was looking for. I know I can have a different method and it would be clearer, but I actually needed to know this. Thanks. – Oiproks Sep 03 '19 at 10:55
  • 1
    @Oiproks Yes, never do this. Code like this would result: `coords.X = 10; Trace.Assert(coords.X == 10); // Throws!`. We treat any such behaviour with properties as a bug. – Matthew Watson Sep 03 '19 at 11:02
  • Thanks @MatthewWatson for the clarification. I'll follow your suggestion. – Oiproks Sep 03 '19 at 11:35
0

You get a recursion, because you again call the same property, which in turn calls the same property, which in turn calls the same property... you get the point.

public int X { get {return X;} set{ X *= 10;} }

How does auto properties works ?
Behind the scenes Properties are actually methods, which means they don't actually store data. So who saves the data ? AutoProperties generate private backend field to save the data.

So in the simple declaration of auto property

int X { get; set; }

The compiler translate it into something like that

private int <X>k__BackingField;

public int X
{
    [CompilerGenerated]
    get
    {
        return <X>k__BackingField;
    }
    [CompilerGenerated]
    set
    {
        <X>k__BackingField = value;
    }
}

So no matter if you use it as Auto Properties or simple property, they are the same.

Now, to answer you question, with paraphrasing, "How do i return the value multiply with 10"

You can solve it with using 2 ways: 1. By saving the data multiply by 10 (setter implementation) 2. By returning the data multiply by 10 (getter implementation)

I won't elavorate, which one you should use, because for this kind of simple scenario, both will be perfectly valid. I would just say that some of the factors for the choice will be micro(micro micro micro) performence, true state storage.

Here is the setter implementation

private int _x;
public int X
{
    get
    {
        return _x;
    }

    set
    {
        return _x*10;
    }
}
Orel Eraki
  • 11,940
  • 3
  • 28
  • 36