Home > Back-end >  C# Generics on Fields
C# Generics on Fields

Time:12-21

I have a dictionary public readonly Dictionary<NetworkSide, PacketHandler<IPacketListener>> Handlers = new();. IPacketListener can be of multiple types, like IClientPacketListener or IServerPacketListener (both extend IPacketListener). The issue is that I cannot add to the dictionary using the method below, because the compiler thinks that it's not possible to convert source type PacketHandler<T> to target type PacketHandler<IPacketListener>, even tho T extends IPacketListener. Any way to get around this?

public readonly Dictionary<NetworkSide, PacketHandler<IPacketListener>> Handlers = new();

public Add<T>(NetworkSide side, PacketHandler<T> handler) where T : IPacketListener {
    Handlers[side] = handler;    <<< Error
}

I have tried to generify the Dictionary using public readonly <T> Dictionary<NetworkSide, PacketHandler<T>> where T : IPacketListener = new();, but something like this is not allowed in C#.

For Java, this would be really easy to do using a wildcard public Map<NetworkSide, PacketHandler<? extends PacketListener>> handlers = new ...;

I know it must be possible somehow...

CodePudding user response:

There's a slight difference between using a T and incorporating an interface. Hope the below clarifies it for you:

using System;
using System.Collections.Generic;
                    
public class Program
{
    public static void Main()
    {
        var handler = new PacketHandler();
        var impl = new PacketHandlerImplementation<PacketHandler>();
        
        Console.WriteLine("You're awesome");
    }
    
    public interface IPacketListener
    {
    }
    
    public class PacketHandler
        : IPacketListener
    {
            
    }
    
    public class PacketHandlerImplementation<T>
        where T : IPacketListener
    {
            
    }
    
    public class DictionaryTest
    {
        public readonly Dictionary<string, PacketHandlerImplementation<IPacketListener>> Handlers;

        public static void Add<T>(string side, PacketHandlerImplementation<T> handler) 
            where T : IPacketListener
        {
                
        }
    }
}

CodePudding user response:

I fixed it by simply casting my generic parameter to the interface type... this._handlers[side] = (IPacketHandler<IPacketListener>) handler;

  • Related