Best practice to implement a Zero Touch node that modifies an input

Suppose I am creating a ZTList Zero Touch library, and it has the following classes:

  • ZTElement: stores an integer property
  • ZTList: keeps a list of ZTElements

These classes are implemented as follows.

ZTElement.cs:

namespace ZTList
{

public class ZTElement
{
    protected int _i = 0;

    public int I
    {
        get { return _i; }
    }

    protected ZTElement(int i)
    {
        _i = i;
    }

    static public ZTElement Create(int i)
    {
        ZTElement ztElement = new ZTElement(i);
        return ztElement;
    }
}

}

ZTList.cs:

namespace ZTList
{

public class ZTList
{
    List<ZTElement> ztElementList = new List<ZTElement>();

    public List<ZTElement> GetList()
    {
        return ztElementList;
    }

    protected ZTList()
    {

    }

    static public ZTList Create()
    {
        return new ZTList();
    }

    public ZTList Add(ZTElement ztElement)
    {
        ztElementList.Add(ztElement);
        return this;
    }
}

}

So the ZTList.Add() method modifies the ZTList instance by adding a ztElement to the intrinsic list.

Then I make the following graph.

This is supposed to add one ztElement to the ztList. Now the problem is, if I disconnect any input to the ZTList.Add() node and reconnect it again, I am adding the same ztElement to the ztList. The screenshot below shows the state of the graph after a few re-connections.

I believe I am not using the correct philosophy here. This may be more sensible in an ordinary Object-Oriented Programming environment, but perhaps this is not recommended in Dynamo. So I am just wondering what the best practice is.

  1. Should I deep copy the input ztList, thus making copies of the existing ztElements in the list?
  2. Or is this a bad node design altogether, and such modification should not be allowed?

Many thanks,
John

usually nodes in a data flow language should return immutable objects - unless your use case requires something else.