4

What I want to do is allow the public incrementation of an integer value within my class, but not allow it to be publicly set explicitly.

I know that I can create a function like this:

void IncrementMyProperty()

but I'd like to allow the user to just do this:

MyClass.Property++;

without allowing this:

MyClass.Property = <SomeInt>;

It's merely for convenience. I'm just wondering if there is any way to do it.


Here's an example:

class MyClass
{
    private int _count;

    public int Count
    {
        get { return _count; }
        private set { _count = value; }
    }

    public void AddOne()
    {
        _count++;
    }
}

class Program
{
    static void Main()
    {
        MyClass example;

        for (int i = 0; i < 10; i++)
            example.Count++;
    }
}

Obviously this won't compile. It's just to show what I'd like to do.

OneHoopyFrood
  • 3,829
  • 3
  • 24
  • 39
  • 1
    This isnt possible without doing some goofy stuff like the mentioned operator overloading. It may be for convenience but you end up producing code that is hard to maintain. – CSharpie Sep 29 '14 at 22:38
  • That's what I figured. Thanks though! – OneHoopyFrood Sep 29 '14 at 22:39
  • Whose convenience? The method way is a clear and predictable solution. Allowing ++ but not = is not so much convenient but confusing, or are you all alone? – TaW Sep 29 '14 at 23:29
  • @TaW I don't see it being confusing. In theory, if someone else tried to use my class wrong my using `=` they would receive an exception that explains why it can't be used that way. It was just a quandary anyhow. – OneHoopyFrood Sep 29 '14 at 23:35

3 Answers3

4

Well, it's possible, but the solution is pretty ugly.

You can create a type that overloads the ++ operator, and make a property of that type where the setter does nothing. That will allow you to use the ++ operator on the property, but it's not possible to actually set the property using the property setter:

class MyValue {

  public int Value { get; private set; }

  public MyValue(int value) {
    Value = value;
  }

  public static MyValue operator ++(MyValue v) {
    v.Value++;
    return v;
  }

}

class MyClass {

  private MyValue _count = new MyValue(0);

  public MyValue Count {
    get { return _count; }
    set { }
  }

}

Usage:

MyClass c = new MyClass();
c.Count++;
Console.WriteLine(c.Count.Value); // outputs 1

So... using the ++ operator in that way is not a good solution. Normally you don't have a setter that does nothing, that will only be confusing. Having a method that increases the counter is not as short as writing ++, but it won't be confusing as long as you name it so that it's clear what it does.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • This answer includes a detailed explanation of not only _how_ to do this, but why you _should not_. It provides a means to accomplish what I originally asked. Thus I feel it must be named the accepted answer. The other answers are very informative and should be viewed as well by any future reader. – OneHoopyFrood Sep 29 '14 at 23:02
3

There's no way. MyClass.MyProperty++ literally translates to MyClass.MyProperty = MyClass.MyProperty + 1, which uses a "setter" and if you allow a "setter" accessor then you would allow, for example, MyClass.MyProperty = <any value>;

OneHoopyFrood
  • 3,829
  • 3
  • 24
  • 39
Saturn K
  • 2,705
  • 4
  • 26
  • 38
  • 1
    It actually calls the `++` operator (that is, it is *not* a literal direct translation). However I believe the re-assignment is inescapable. – user2864740 Sep 29 '14 at 22:39
  • @Keyvan Sadralodabai I figured as much. Thanks for confirming. – OneHoopyFrood Sep 29 '14 at 22:41
  • 1
    I tried playing around with making Count be a class with overloaded operator ++. Did not work. The gotcha is that operator ++ is a static function that returns a new instance. The set accessor is being called. I'll post the code if anyone wants to see. – KC-NH Sep 29 '14 at 23:47
1

not if you increment the int property. but you could write example++ and overload the ++ operator for your class to increment Count, while removing its setter.

ths
  • 2,858
  • 1
  • 16
  • 21
  • 1
    Yes, this is the right method. But it's not exactly what I was trying to do. The actual implementation is inside a much more complex class. Thanks for your help! – OneHoopyFrood Sep 29 '14 at 22:44