32

I have an object with a property for which I want to create a custom setter and also keep the automatic getter:

public class SomeObject
{
   public int SomeProp { get; set; }
   public Nullable<short> MyProp
   {
      get
      {
         return MyProp;
      }
      set
      {
         if (value != null)
         {
            SomeProp = SomeWork(value);
            MyProp = value;
         }
      }
   }
}

The problem is that I get a Stackoverflow error on the getter. How do I implement a property where I keep the getter as it is but only modify the setter?

Raktim Biswas
  • 4,011
  • 5
  • 27
  • 32
frenchie
  • 51,731
  • 109
  • 304
  • 510
  • 15
    You can't. You need a field. – SLaks Aug 09 '16 at 18:52
  • In this case, you need a 2nd field. Otherwise, you get an infinite loop in the getter – Don Cheadle Aug 09 '16 at 18:55
  • 4
    I don't get it, whats with all the downvotes? – Steve Aug 09 '16 at 18:56
  • 2
    @Steve I was actually going to ask the same thing - it's a perfectly reasonable question in my opinion, I've wanted to do the exact same thing in C# lots of times. Besides, it's always kind of annoyed me when people downvote without commenting to explain why. – EJoshuaS - Stand with Ukraine Aug 09 '16 at 18:58
  • Ok, got it; just never had this edge case before. – frenchie Aug 09 '16 at 18:58
  • @mmcrae you're correct but just a minor semantics point: it's infinite *recursion*, not an infinite loop - an infinite loop doesn't necessarily grow the stack like recursion does (in fact, it generally won't) so you'd see somewhat different behavior in that case. – EJoshuaS - Stand with Ukraine Aug 09 '16 at 19:02
  • 1
    The reason I bring that last point up is there are valid use cases for infinite loops, and doing that won't cause an exception if properly implemented; however I don't think there's a way to prevent this kind of recursion from causing a stack overflow exception (last I checked C# didn't support tail recursion *per se* yet, correct me if I'm wrong), so there's no legitimate use case for it. – EJoshuaS - Stand with Ukraine Aug 09 '16 at 19:58

4 Answers4

31

You need to use a backing field for your property. You're getting a SO error because you're recursively referencing your MyProp property in its own getter resulting in infinite recursion.

private short? _myProp;

public short? MyProp
{
    get
    {
        return _myProp;
    }
    set
    {
        if (value != null)
        {
            SomeProp = SomeWork(value);
            _myProp = value;
        }
    }
}
rory.ap
  • 34,009
  • 10
  • 83
  • 174
8

NO, it's not possible. Either you make it a complete auto property (OR) define both the getter and setter in which case you will have to provide the backing field since compiler won't create one for you.

Rahul
  • 76,197
  • 13
  • 71
  • 125
4

You get the exception because you're essentially doing infinite recursion in your property.

Unfortunately what you're describing isn't possible in C# yet, you need to define the backing field yourself.

  • Will it ever be implemented? I wonder... – rory.ap Aug 09 '16 at 19:01
  • 1
    @roryap, I don't think so and neither see a logic / benefit for implementing that. – Rahul Aug 09 '16 at 19:02
  • @roryap I hope it eventually does, maybe I'm a bit obsessive but it's always pained me slightly having to have the extra field. Although now that I think about it the problem with that is that once you're doing a custom implementation there's no guarantee anymore as to where the value is actually coming from. – EJoshuaS - Stand with Ukraine Aug 09 '16 at 19:06
  • 2
    @Rahul one purpose would be for information hiding from your own class. If assignments should always go through the same validation code, this feature would allow the developer to leave theirself only that route of changing the value. – Uueerdo Aug 09 '16 at 19:50
4

You cannot do that. You either use custom getter setters (both, not single) or you stick to auto getters.

In your code getter of your property is trying to access getter of itself (which is going to access the same getter and so on and so on)

So it's an endless loop which is going to destroy all the world and bring the end of humanity

Hasan
  • 2,444
  • 3
  • 30
  • 44