Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

.net - C# generic handlers, what am I misunderstanding?

I'm not sure why this doesn't work. It doesn't like TResponse for the out and handlerMap add, even though TResponse is an IResponse? I figure I must be misunderstanding something about generics, or perhaps more likely, about C#. Why doesn't this work, and is there a better way to accomplish what I'm trying to do here?

private static Dictionary<Type, List<IResponseHandler<IResponse>>> _handlerMap;

public static void AddResponseHandler<TResponse>(IResponseHandler<TResponse> handler) where TResponse : IResponse
{
    List<IResponseHandler<TResponse>> handlers;
    _handlerMap.TryGetValue(typeof (TResponse), out handlers);

    if (handlers == null)
    {
        handlers = new List<IResponseHandler<TResponse>>();
        _handlerMap.Add(typeof (TResponse), handlers);
    }

    handlers.Add(handler);
}

public interface IResponseHandler<TResponse> where TResponse : IResponse
{
    void Handle(TResponse response);
}

I am getting these errors during compilation:

Error 1 The best overloaded method match for 'System.Collections.Generic.Dictionary>>.TryGe??tValue(System.Type, out System.Collections.Generic.List>)' has some invalid arguments C:...NetworkManager.cs 39 13 Assembly??-CSharp-vs

Error 2 Argument 2: cannot convert from 'out System.Collections.Generic.List>' to 'out System.Collections.Generic.List>' C:...NetworkManager.cs 39 61 Assembly-CSharp-vs

If I change TResponse to IResponse within the method, everything above
handlers.Add(handler) compiles fine. I don't understand why I can't add a handler of 
<TResponse : IResponse> to a List<IResponseHandler<IReponse>>?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The variance in C# doesn't allow you to assign an IResponseHandler<IResponse> to an IResponseHandler<T> even if there's where clause on T.

I can't tell what you're trying to do because you haven't provided all the code that's in use here; but, this will compile:

public class SomeClass<TResponse> where TResponse : IResponse
{
    private static Dictionary<Type, List<IResponseHandler<TResponse>>> _handlerMap;

    public static void AddResponseHandler(IResponseHandler<TResponse> handler) 
    {
        List<IResponseHandler<TResponse>> handlers;
        _handlerMap.TryGetValue(typeof(TResponse), out handlers);

        if (handlers == null)
        {
            handlers = new List<IResponseHandler<TResponse>>();
            _handlerMap.Add(typeof(TResponse), handlers);
        }

        handlers.Add(handler);
    }       
}

This moves the generic from the method to the class so you can define a compatible _handlerMap.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...