76 votes

Les arguments de type pour la méthode ne peuvent pas être déduits de l'utilisation

Peut-être que je suis surmené, mais ce n'est pas une compilation (CS0411). Pourquoi?

 interface ISignatur<T>
{
    Type Type { get; }
}

interface IAccess<S, T> where S : ISignatur<T>
{
    S Signature { get; }    
    T Value { get; set; }
}

class Signatur : ISignatur<bool>
{
    public Type Type
    {
        get { return typeof(bool); }
    }
}

class ServiceGate
{
    public IAccess<S, T> Get<S, T>(S sig) where S : ISignatur<T>
    {
        throw new NotImplementedException();
    }
}

static class Test
{
    static void Main()
    {
        ServiceGate service = new ServiceGate();
        var access = service.Get(new Signatur()); // CS4011 error
    }
}

Quelqu'un a une idée pourquoi pas ? Ou comment résoudre ?

92voto

Kirk Woll Points 34601

Get<S, T> prend deux types d'arguments. Lorsque vous appelez service.Get(new Signatur()); comment le compilateur sait-il ce qu'est T ? Vous devrez le transmettre explicitement ou modifier autre chose à propos de vos hiérarchies de types. Le passer explicitement ressemblerait à:

 service.Get<Signatur, bool>(new Signatur());

1voto

Comme je l'ai mentionné dans mon commentaire, je pense que la raison pour laquelle cela ne fonctionne pas est que le compilateur ne peut pas déduire de types basés sur des contraintes génériques.

Vous trouverez ci-dessous une implémentation alternative qui compilera. J'ai révisé l'interface IAccess pour n'avoir que le paramètre de type générique T

 interface ISignatur<T>
{
    Type Type { get; }
}

interface IAccess<T>
{
    ISignatur<T> Signature { get; }
    T Value { get; set; }
}

class Signatur : ISignatur<bool>
{
    public Type Type
    {
        get { return typeof(bool); }
    }
}

class ServiceGate
{
    public IAccess<T> Get<T>(ISignatur<T> sig)
    {
        throw new NotImplementedException();
    }
}

static class Test
{
    static void Main()
    {
        ServiceGate service = new ServiceGate();
        var access = service.Get(new Signatur());
    }
}

1voto

Je voulais faire un exemple simple et compréhensible

si vous appelez une méthode comme celle-ci, votre client ne saura pas le type de retour

 var interestPoints = Mediator.Handle(new InterestPointTypeRequest
            {
                LanguageCode = request.LanguageCode,
                AgentId = request.AgentId,
                InterestPointId = request.InterestPointId,
            });

Ensuite, vous devriez dire au compilateur que je sais que le type de retour est List<InterestPointTypeMap>

 var interestPoints  = Mediator.Handle<List<InterestPointTypeMap>>(new InterestPointTypeRequest
            {
                LanguageCode = request.LanguageCode,
                AgentId = request.AgentId,
                InterestPointId = request.InterestPointId,
                InterestPointTypeId = request.InterestPointTypeId
            });

le compilateur ne vous en voudra plus de connaître le type de retour

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X