Comment résoudre l’ambiguïté des appels entre Generic.IList<T>.this[] et IList.this[] ?

StackOverflow https://stackoverflow.com/questions/57054

Question

J'ai une collection qui implémente une interface qui étend à la fois IList<T> et List.

public Interface IMySpecialCollection : IList<MyObject>, IList { ... }

Cela signifie que j'ai deux versions de l'indexeur.

Je souhaite que l'implémentation générique soit utilisée, donc j'implémente celle-là normalement :

public MyObject this[int index] { .... }

J'ai seulement besoin de la version IList pour la sérialisation, donc je l'implémente explicitement, pour la garder cachée :

object IList.this[int index] { ... }

Cependant, dans mes tests unitaires, ce qui suit

MyObject foo = target[0];

entraîne une erreur du compilateur

L'appel est ambigu entre les méthodes ou propriétés suivantes

Cela me surprend un peu ;Je crois que je l'ai déjà fait et ça marche bien.Qu'est-ce que j'oublie ici?Comment puis-je faire coexister IList<T> et IList au sein de la même interface ?

Modifier IList<T> fait pas implémenter IList, et je doit implémentez IList pour la sérialisation.Les solutions de contournement ne m'intéressent pas, je veux savoir ce qui me manque.

Modifier à nouveau:J'ai dû supprimer IList de l'interface et le déplacer dans ma classe.Je ne veux pas faire cela, car les classes qui implémentent l'interface seront finalement sérialisées en Xaml, ce qui nécessite que les collections implémentent IDictionary ou IList...

Était-ce utile?

La solution

Tu ne peux pas faire ça avec

public interface IMySpecialCollection : IList<MyObject>, IList { ... }

Mais vous pouvez faire ce que vous voulez avec une classe, vous devrez rendre explicites les implémentations de l’une des interfaces.Dans mon exemple, j'ai rendu IList explicite.

public class MySpecialCollection : IList<MyObject>, IList { ... }

IList<object> myspecialcollection = new MySpecialCollection(); IList list = (IList)myspecialcollection;

Avez-vous envisagé de demander à IMySpecialCollection d'implémenter ISerializing pour la sérialisation ?Prendre en charge plusieurs types de collections me semble un peu faux.Vous pouvez également envisager de convertir votre IList en IEnumerable pour la sérialisation, car IList encapsule simplement IEnumerable et ICollection.

Autres conseils

C'est une dupe de ma question ici

Pour résumer, si vous faites cela, cela résout le problème :

public Interface IMySpecialCollection : IList<MyObject>, IList
{
    new MyObject this[int index];
    ... 
}

Malheureusement, vous ne pouvez pas déclarer deux indexeurs avec la même liste de paramètres.Le paragraphe suivant est tiré d'ici Guide de programmation C# - Utilisation de la section « Remarques » des indexeurs:

La signature d'un indexeur est constituée du nombre et des types de ses paramètres formels.Il n'inclut pas le type d'indexeur ni les noms des paramètres formels.Si vous déclarez plusieurs indexeurs dans la même classe, ils doivent avoir des signatures différentes.

Vous devrez déclarer un ensemble de paramètres différent si vous souhaitez utiliser le deuxième indexeur.

Changez votre implémentation générique en...

T IList<T>.this[int index] { get; set; }

Cela dit explicitement quel « ceci » est lequel.

List<T> implique IList, c'est donc une mauvaise idée d'utiliser les deux dans la même classe.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top