2010-10-27 8 views
2

J'ai une interface générique en C#, et presque toujours je l'utilise avec l'un des types. Je veux créer une interface non générique pour ce type et l'utiliser.Interface non-générique comme synonyme de générique

Disons que j'ai le code suivant:

public interface IMyGenericList<out T> where T : IItem 
{ 
    IEnumerable<T> GetList(); 
} 

public class MyList<T> : IMyGenericList<T> where T : IItem 
{ 
    public IEnumerable<T> GetList() 
    { 
     return null; 
    } 
} 

il fonctionne bien. La plupart du temps j'ai besoin IMyGenericList<IItem>, donc j'essayer les éléments suivants:

public interface IMyItemsList : IMyGenericList<IItem> 
{ 
} 

mais je ne peux pas faire MyList mettre en œuvre IMyItemsList pour une raison quelconque. Le code suivant renvoie une erreur

public class MyList<T> : IMyItemsList, IMyGenericList<T> where T : IItem 
{ 
    public IEnumerable<T> GetList() 
    { 
     return null; 
    } 
} 

disant que IEnumerable<IItem> is not implemented.

Pourquoi est-ce que/que puis-je faire avec ceci? Merci.

Ok, grâce à vos réponses j'ai compris qu'il est impossible de le faire exactement comme je le voulais initialement. Je signalerai une autre question pourquoi cela est impossible :) voici: One function implementing Generic and non-generic interface

+0

Où est votre méthode 'GetEnumerator'? – leppie

+0

Je n'implémente pas IEnumerable, je retourne juste une valeur avec ce type – Shaddix

+0

"La plupart du temps j'ai besoin de' IMyGenericList '". Vous ne pouvez l'avoir que grâce à votre contrainte de type. –

Répondre

2

Vous exemple précis ne fonctionnerait pas, comme votre classe:

public class MyList<T> : IMyItemsList, IMyGenericList<T> where T : IItem 
{ 
    public IEnumerable<T> GetList() 
    { 
    return null; 
    } 
} 

tente de mettre en œuvre à la fois un IEnumerable<IItem> GetList() et un IEnumerable<T> GetList(), qui sont deux choses différentes. Cette première est explicitement une énumérable de IItem (comme requis par votre interface IMyItemsList), et la seconde est un énumérable de T.

Dans ce scénario T est de type IItem mais n'est pas explicitement IItem. Par conséquent lors de la compilation, le IEnumerable<IItem> GetList() n'est pas IEnumerable<T> GetList() donc le compilateur lancera correctement une erreur vous indiquant que IEnumerable<IItem> GetList() n'est pas implémenté.

L'autre problème que vous courrez dans, est ce qui se passe quand quelqu'un fait:

var list = new MyList<IItem>(); 

Le compilateur va essayer de créer une mise en œuvre concrète de MyList<IItem> qui aura deux définitions de IEnumerable<IItem> GetList().

Je voudrais reconsidérer votre conception pour évaluer un singulier IEnumerable<T> GetList().

aussi, et juste pointilleux de ma part: "dénombrable" = "liste": P

+0

imho, IEnumerable où T: IItem peut toujours être casté en IEnumerable , n'est-ce pas? Je pensais, c'est ce que la covariance est pour .net? Je suis d'accord avec vous, il semble laid et entraînera des problèmes pour avoir une implémentation IEnumerable explicite IEnumerable GetList() – Shaddix

1

Vous ne pouvez pas avoir votre interface IMyItemsList héritée de IMyGenericList<out T> interface si vous voulez avoir MyList<T> mettre en œuvre les deux. Mais vous pouvez modifier votre interface IMyItemsList tel que défini ci-dessous:

public interface IItem 
{ 
} 

public interface IMyItemsList 
{ 
    IEnumerable<IItem> GetList(); 
} 

public interface IMyGenericList<out T> where T : IItem 
{ 
    IEnumerable<T> GetList(); 
} 

public class MyList<T> : IMyGenericList<T>, IMyItemsList 
    where T : IItem 
{ 
    public IEnumerable<T> GetList() 
    { 
     return null; 
    } 

    IEnumerable<IItem> IMyItemsList.GetList() 
    { 
     return this.GetList().Cast<IItem>(); 
    } 
} 
Questions connexes