2017-10-09 4 views
3

J'ai ces 2 interfaces:Type Résultat covariance - classe générique avec la méthode de retour à la fois un type d'interface et un type spécifique

public interface IResult 
{ 
    object SomeProperty {get;set;} 
} 

public interface IFooManager 
{ 
    IResult GetResult(string someId); 
} 

Je voudrais mettre en œuvre un IFooManager dans une classe générique de cette façon:

public class MyFooManager<T> : IFooManager where T: class, IResult 
{ 
    public T GetResult(string id) 
    { 
     return null; //the value doesn't really matter here 
    } 
} 

Cependant, il en résulte une erreur de compilation:

Cannot implement method from interface [..].IFooManager. Return type should be [..].IResult

Maintenant, je sais que je pourrais résoudre ce problème en définissant en outre la méthode d'interface explicitement, comme ceci:

IResult IFooManager.GetResult(string id) 
{ 
    return GetResult(id); 
} 

Mais les questions est la suivante: pourquoi ne peut pas le compilateur juste comprendre, que T GetResult() retourne en effet un objet mettant en œuvre IResult? Je sais que je pourrais probablement introduire une interface de covariance out T en plus de cela, mais je ne peux pas le rayer de ma tête - pourquoi la restriction de type T ne suffit pas pour assurer la sécurité du type?

+1

Il n'y a aucune raison pour que le compilateur n'effectue pas de covariance de type return pour la fonction, sauf que le langage ne le supporte pas (et il ne le supporte probablement pas car le runtime ne le supporte pas) . Vous pourriez voir ce code fonctionner dans d'autres langues. – milleniumbug

+0

Il peut simplement rendre son interface générique aussi, et faire retourner la méthode par T. – Mishka

+1

[Pourquoi C# ne déduit-il pas mes types génériques?] (Https://stackoverflow.com/questions/8511066/why-doesnt-c-sharp -infer-my-generic-types) –

Répondre

3

Parce que:

IResult GetResult(string someId); 

n'est pas la même chose que:

T GetResult(string id) 

Vous avez dit au compilateur avec la contrainte que T est une classe qui implémente IResult - pas IResult. Ces 2 choses ne sont pas les mêmes.