27

I have a property which is currently automatic.

public string MyProperty { get; set; }

However, I now need it to perform some action every time it changes, so I want to add logic to the setter. So I want to do something like:

public string MyProperty {
    get;
    set { PerformSomeAction(); }
}

However, this doesn't build... MyProperty.get' must declare a body because it is not marked abstract, extern, or partial

I can't just have the getter return MyProperty as it will cause an infinite loop.

Is there a way of doing this, or do I have to declare a private variable to refer to? I'd rather not as MyProperty is used through out the code both in this class and outside it

komodosp
  • 3,316
  • 2
  • 30
  • 59

5 Answers5

25

You need to use a property with backing field:

private string mMyProperty;
public string MyProperty
{
    get { return mMyProperty; }
    set
    {
        mMyProperty = value;
        PerformSomeAction();
    }
}
Marius
  • 562
  • 5
  • 26
  • 18
    This is sad, isn't it. I mean why would they allow something like `string myStr { get; private set; }` but not `{ get; set { ... } }`. – Parziphal Apr 30 '17 at 17:27
  • @Parziphal Agree, it is really odd to allow one but not the other – Kellen Stuart Mar 19 '19 at 15:46
  • it's simple, in the first case you have a backing field that is generated and you give them the responsibility to implement the setter and getter using it. In the second case you want a backing field in the get but not in the set, which is a problem. Otherwise it would beg the question- how will you modify the invisible backing field in the set? – Evyatar Dec 30 '20 at 12:38
  • @Evyatar It's simple, they already provide syntax for "value", you just add another syntax for the implicit backing field. – Austin Salgat Apr 21 '22 at 03:09
6

You can´t implement one without the other, as when using the one it refers to a (hidden) backing-field which is auto-generated in the case of an autogenerated property. However when you implement one you have to set this backing-field in both ways.

The auto-way is just a shortcut for this:

private string _property;
public string MyProperty
{
    get { return _property; }
    set { _property = value; }
}

So if you´d omit the hidden field in one of the methods (this is what getters and setters are actually) how should this method know how to store/get the value?

Jonesopolis
  • 25,034
  • 12
  • 68
  • 112
MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111
2

You need to either provide a body for both the getter and setter, or neither.

So if you define either one, it's no longer an auto property.

So you have to do:

Either

public string MyProperty {
    get;
    set;
}// Automatic property, no implementation

OR

public string MyProperty
{
    get { return mMyProperty; }
    set
    {
        mMyProperty = value;
        PerformSomeAction();
    }
}
Vishal Suthar
  • 17,013
  • 3
  • 59
  • 105
0

If you are doing something in the setter then you will have to explicitly declare the variable. E.g.

private string _myProperty;
public string MyProperty {
    get { return _myProperty; };
    set 
    {
        _myProperty = value; 
        PerformSomeAction(); 
    }
}

or - in the setter you can pass value to the function and do what you want to it there... assuming you want to change/check the value in the function PerformSomeAction()

Percy
  • 2,855
  • 2
  • 33
  • 56
0

This is similar to the question C# getter and setter shorthand.

When you manually specify a setter, it won't use the automatic property mechanism for the getter, which is why the error message acts like it's missing. You'll need to write your own getter when you specify the setter.

Community
  • 1
  • 1
Trevor
  • 33
  • 6