2009-04-29 5 views
1

je tente de déclarer et utiliser une interface comme ceci:mal à définir un IList <T> où T est une interface générique

public interface IItem<T> 
{ 
    string Name { get; set; } 
    T Value { get; set; } 
} 

Cela fonctionne bien jusqu'à ce que je tente de créer une liste de ces articles. Cela ne compile pas:

public interface IThing 
{ 
    string Name { get; } 
    IList<IItem<T>> ThingItems { get; } 
} 

donc je ne suis pas certain où le problème est. La valeur des éléments n'est pas définie avant l'exécution, et j'ai besoin d'avoir des collections des éléments. Je me dis que c'est un modèle assez standard, mais je ne vois pas où je suis en train de tomber.

Répondre

2

Vous tombez parce que le compilateur veut savoir quels types d'éléments sont dans votre liste. Donc, si vous ne créez savez pas encore, juste une interface de base non générique, et d'en tirer une interface plus spécifique générique:

Peut-être que cela vous aide:

public interface IItem 
{ 
    string Name { get; set; } 
} 

public interface IItem<T>: IItem 
{ 
    T Value { get; set; } 
} 

public interface IThing 
{ 
    string Name { get; } 
    IList<IItem> Items { get; } 
} 

public interface IThing<T>: IThing 
{ 
    string Name { get; } 
    IList<IItem<T>> Items { get; } 
} 
+0

Dans votre exemple, vous voulez que IItem ait toujours la propriété value, retourne simplement l'objet. –

+0

Cela dépend si vous en avez besoin. Peut-être voudriez-vous aussi exposer le type de l'élément (par exemple, quel type (T) renvoie), etc. S'il existe des méthodes non génériques sur l'interface (comme, ProcessItem), vous n'avez probablement pas besoin de la valeur de l'objet car ils seront en mesure d'utiliser la valeur générique dans leur mise en œuvre. – Lucero

+0

Cela vient aussi près que je pense que je peux. Je n'aurais jamais l'interface finale que vous avez ici IThing que les éléments varient indépendamment des choses. –

6

Votre classe doit également être générique (Thing<T>) sinon la liste ne peut pas savoir quel type utiliser.

public interface Thing<T> 
{ 
    string Name { get; } 
    IList<IItem<T>> thingItems { get; } 
} 

EDIT Il est compilée.

EDIT Il vous semble voulez que votre IItem<T> être en termes de tout type. Cela ne fonctionnera pas en C#. Vous pouvez créer IList> ici, mais c'est loin d'être idéal, puisque vous perdez votre saisie lorsque vous voulez sortir les objets.

+0

Ceci ne sera pas compilé! –

+0

Ne compilera pas. Vous ne pouvez pas avoir de champs dans une interface. – dirkgently

+0

Mais cela ne fonctionnera pas dans le cas indiqué. Les types d'éléments dans thingItems varient en fonction de l'élément, pas de la chose. –

2
  • interfaces ne peuvent pas contenir des champs (données membres)
  • Un type contenant un type générique est aussi un type générique
2

Deux problèmes:

  1. Vous ne pouvez pas déclarer champs un interface. (justification: un champ est considéré comme un détail d'implémentation, ce qui est l'objet que les interfaces sont conçues pour éliminer)
  2. Vous ne pouvez pas avoir de champ générique sans spécifier le paramètre type (sauf si vous avez un paramètre de type sur le type de déclaration aussi)).
0

Lorsque vous créez un instace de Thing vous devez savoir quel est le type de Thing.thingItems. Donc, ce qui suit est la bonne façon.

public interface Thing<T> 
{ 
    String Name { get; } 
    IList<IItem<T>> thingItems { get; } 
} 

Si vous ne connaissez pas le type au point concret de instancier Thing vous ne pouvez utiliser une classe de base commune ou une interface commune pour le type.

public interface Thing<T> 
{ 
    String Name { get; } 
    IList<IItem<ThingParameterBase>> thingItems { get; } 
} 

Ou avec une interface commune.

public interface Thing<T> 
{ 
    String Name { get; } 
    IList<IItem<IThingParameter>> thingItems { get; } 
} 
+0

Je pourrais le faire IList > ThingItems je suppose. Je sens juste que ça sent le paradis. –

+0

... et cela vous donnerait des problèmes de covariance, car un IItem n'est pas compatible avec IItem ! – Lucero

Questions connexes