Question: I need to constantly add and remove actions to the delegate, should I use a hashset instead of actions?

What I currently have:

```
System.Action _callbacks =null;

//...somewhere in code, from many different places (2000 places or so, every frame):
_callbacks -= anyFunction;
_callbacks += someOtherFunc; 

```

What I might use instead (basically a Hashset of callbacks):

```
Hashset<FastFunc> _callbacks = new Hashset<FastFunc>();

//...somewhere in code, from many different places
_callbacks.add( new FastFunc(someOtherFunc) );

// works A LOT faster with hashsets  that System.Action does.  //(March2019 profiler)
// It remembers its hashcode once, then can provide it super-quickly every time it's required.
public class FastFunc{
    public System.Action _func;
    private int _hashCode;

    public FastFunc(System.Action function){
        _func = function;
        remember_HashCode(function);
    }

    public override int GetHashCode(){
        return _hashCode;
    }

    // important to override Equals as well, so that objects created from the same method
    // will be identical.
    public override bool Equals(object other){    
        System.Action otherAction = ((FastFunc)other)._func;

        bool isEqual =  otherAction.Method.Equals( _func.Method )  &&  otherAction.Target.Equals( _func.Target );
        return isEqual;
    }

    //only called once, during constructor
    void remember_HashCode(System.Action myFunc){
        _hashCode = myFunc.GetHashCode();
    }
}

```

With this -= and += operators is ok to subscribe to the `System.Action`, or not?

Does it use an array under the hood, which will have to be shifted-back if we remove some function from its start index? If it does, I guess hashset would be a better choice + no duplicates.

Answer: 
Invocation lists of multicast delegates *are* arrays.

<https://referencesource.microsoft.com/#mscorlib/system/multicastdelegate.cs,284>

(The documentation is outdated (the delegates might have used linked-linsts in .Net 1.0, but not anymore) <https://learn.microsoft.com/en-us/dotnet/api/system.multicastdelegate?view=netframework-4.8> )

You can make the add/remove operations faster with your method. In fact, AFAIR, WPF does that.

You need to be careful about multi-threading though.
See <https://learn.microsoft.com/en-us/dotnet/api/system.multicastdelegate?view=netframework-4.8>

All delagates in . Net are in fact multicast delegates, as per that article they are implemented as a linked list.