简体   繁体   English

变量c#的附加赋值

[英]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#. 我知道事件在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. 这将把NewEvent添加到调用myEventHandler时运行的事件链。

I want to be able to do something similar. 我希望能够做类似的事情。 I want to create a Graph class which models mathematical graphs with nodes and connections. 我想创建一个Graph类,它用节点和连接建模数学图。 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. Graph类将具有nodes属性,该属性应该只能添加或删除节点,但不能设置为整个属性。

Once again using the EventHandler example, I can't do the following with EventHandler 再次使用EventHandler示例,我无法使用EventHandler执行以下操作

myEventHandler = OnlyOneEventWillRun;

I also want to be able to implement logic to the addition assignment similar to the set{} accessor. 我还希望能够为添加赋值实现类似于set{}访问器的逻辑。

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. 对于初学者来说, myEventHandler是一个多播委托 - 你可以自己动手来反映这个功能,但这并没有真正解决你所说的问题。

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): 我将采用的方法是使用私有的setter(或根本没有setter) - 这将允许你从定义属性的类中设置值(大概你会知道并记住你在做什么)但不是来自课外(另一位开发人员无意中搞砸了):

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);
}

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. Graph类将具有nodes属性,该属性应该只能添加或删除节点,但不能设置为整个属性。

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: 如果你想让你的API更流畅,你可以将Graph对象本身作为AddNode的返回值返回,因此它可以与链式添加一起使用:

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: 和/或接受节点的params数组参数,以便它可以被调用为:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM