How to use template with enum for reader.ReadValueSafe?

Hi, I’m I have a NetworkEventListener:

public class NetworkEventListener
    {
        private Dictionary<ushort, MsgEvent> events = new();

        public void RegisterEvent(ushort commandType, UnityAction<ulong, SerializedData> callback)
        {
            MsgEvent cmdevt = new();
            cmdevt.commandType = commandType;
            cmdevt.callback = callback;
            events.Add(cmdevt.commandType, cmdevt);
        }

        public void OnReceiveNetworkMsg(ulong senderId, FastBufferReader reader)
        {
            reader.ReadValueSafe(out ushort type);
            bool found = events.TryGetValue(type, out MsgEvent networkEvent);
            if (found)
            {
                networkEvent.callback.Invoke(senderId, new SerializedData(reader));
            }
        }

        public class MsgEvent
        {
            public ushort commandType;
            public UnityAction<ulong, SerializedData> callback;
        }
    }

Where I register the events in both client and server by:
Client:

GameNetwork.Singleton.clientEventListener.RegisterEvent((ushort)ServerMsg.PlayerDrawCard, ReceiveDrawCard);

Server:

GameNetwork.Singleton.serverEventListener.RegisterEvent((ushort)ClientMsg.RequestPlayCard, ReceivePlayCard);
    public enum ClientMsg : ushort
    {
        RequestPlayCard,

    }

    public enum ServerMsg : ushort
    {
        PlayerDrawCard,
    }

Where I have to convert ServerMsg and ClientMsg to ushort in order for this to work.

Is it possible that I can directly use ServerMsg/ClientMsg without converting?
I tried to change the NetworkEventListener to template class:

public class NetworkEventListener<T> : System.Enum
...
public NetworkEventListener clientEventListener<ServerMsg> = new();

But
reader.ReadValueSafe(out T type); will have error:
The type ‘T’ cannot be used as type parameter ‘T’ in the generic type or method ‘FastBufferReader.ReadValueSafe(out T, FastBufferWriter.ForNetworkSerializable)’. There is no boxing conversion or type parameter conversion from ‘T’ to ‘Unity.Netcode.INetworkSerializable’.

Not sure how to fix this, I tried to use T: INetworkSerializable but it is no good, which is weird since Enum can be serialized by netcode.

This might work but I’ve not properly tested it:

public class NetworkEventListener<T> where T : unmanaged, Enum
{
    private Dictionary<T, MsgEvent> events = new Dictionary<T, MsgEvent>();

    public void RegisterEvent(T commandType, UnityAction<ulong, SerializedData> callback)
    {
        MsgEvent cmdevt = new MsgEvent();
        cmdevt.commandType = commandType;
        cmdevt.callback = callback;
        events.Add(cmdevt.commandType, cmdevt);
    }

    public void OnReceiveNetworkMsg(ulong senderId, FastBufferReader reader)
    {
        reader.ReadValueSafe<T>(out T type);
        bool found = events.TryGetValue(type, out MsgEvent networkEvent);
        if (found)
        {
            networkEvent.callback.Invoke(senderId, new SerializedData(reader));
        }
    }

    public class MsgEvent
    {
        public T commandType;
        public UnityAction<ulong, SerializedData> callback;
    }
}

Thank you so much, this works like a charm.

Can you explain why adding unmanaged can make the error go away? I don’t really get how the error msg is related to unmanaged. Thanks.

I’m not sure, it looks like as there’s no exact signature match and there’s a few to choose from it’s making a best guess at the one you’re trying to use.