Ansaar Dollie
Ansaar Dollie

Reputation: 49

addition assignment for variable c#

How would I create a property in a class that can only be set using an addition assignment. I know events work this way in C#. I was wondering how I may implement the construct in my own code.

Eg. For Events I can do the following

public event EventHandler myEventHandler;
myEventHandler += NewEvent;

And that will add NewEvent to the chain of events that gets run when myEventHandler is called.

I want to be able to do something similar. I want to create a Graph class which models mathematical graphs with nodes and connections. The Graph class would have a nodes property which should only be able to have nodes added or removed but not set as a whole property.

Once again using the EventHandler example, I can't do the following with EventHandler

myEventHandler = OnlyOneEventWillRun;

I also want to be able to implement logic to the addition assignment similar to the set{} accessor.

Upvotes: 1

Views: 173

Answers (2)

Rotem
Rotem

Reputation: 21917

The Graph class would have a nodes property which should only be able to have nodes added or removed but not set as a whole property.

While this is great for encapsulation, there are simpler and more obvious ways to implement it than overloading the += operator.

Here is one example:

class Graph
{
    private List<Node> nodes;
    public ReadOnlyCollection<Node> Nodes
    {
        get { return new ReadOnlyCollection<Node>(nodes); }
        //note no setter
    }

    public void AddNode(Node node) 
    { 
        //whatever additional logic you need
        nodes.Add(node); 
    }
}

If you want to make your API more fluent, you could return the Graph object itself as the return value from AddNode, so it could be used with chained adds:

graph.AddNode(node1)
    .AddNode(node2)
    .AddNode(node3);

And/or accept a params array parameter for the node(s) so that it could be called as:

graph.AddNode(node1, node2);
graph.AddNode(node3);

Upvotes: 1

Dave Smash
Dave Smash

Reputation: 3001

For starters, myEventHandler is a multicast delegate - you can make your own to mirror that functionality, but that doesn't really solve your problem as you stated.

The approach I would take is to use a private setter (or no setter at all) - this would allow you to set the value from within the class that defines the property (where presumably you will know and remember what you are doing) but not from outside the class (where another developer could unwittingly screw it up):

private List<object> _nodes;    // private backing field
public List<object> Nodes
{
    get
    {
        return _nodes;          // can be "gotten" by any class
    }

    private set                 // can only be set from within this class
    {
        if (value != _nodes)
        {
            // do additional logic

            _nodes = value; // set the backing variable
        }
    }
}

public void AddNode(object Node)
{
    Nodes.Add(Node);
}

public void RemoveNode(object Node)
{
    Nodes.Remove(Node);
}

Upvotes: 2

Related Questions