Как устранить неоднозначность вызова между Generic.IList<T>.this[] и IList.this[]?
Вопрос
У меня есть коллекция, реализующая интерфейс, расширяющий как IList<T>, так и List.
public Interface IMySpecialCollection : IList<MyObject>, IList { ... }
Это означает, что у меня есть две версии индексатора.
Я хочу, чтобы использовалась общая реализация, поэтому я обычно реализую ее:
public MyObject this[int index] { .... }
Мне нужна только версия IList для сериализации, поэтому я реализую ее явно, чтобы скрыть:
object IList.this[int index] { ... }
Однако в моих модульных тестах следующее
MyObject foo = target[0];
приводит к ошибке компилятора
Вызов неоднозначен между следующими методами или свойствами
Я немного удивлен этим;Я считаю, что делал это раньше, и все работает нормально.Что мне здесь не хватает?Как я могу заставить IList<T> и IList сосуществовать в одном интерфейсе?
Редактировать IList<T> делает нет реализовать IList, и я должен реализовать IList для сериализации.Меня не интересуют обходные пути, я хочу знать, чего мне не хватает.
Изменить еще раз:Мне пришлось удалить IList из интерфейса и переместить его в свой класс.Я не хочу этого делать, поскольку классы, реализующие интерфейс, в конечном итоге будут сериализованы в Xaml, а для этого требуются коллекции для реализации IDictionary или IList...
Решение
Вы не можете сделать это с
public interface IMySpecialCollection : IList<MyObject>, IList { ... }
Но вы можете делать с классом все, что хотите, вам нужно будет явно указать реализацию одного из интерфейсов.В моем примере я сделал IList явным.
public class MySpecialCollection : IList<MyObject>, IList { ... }
IList<object> myspecialcollection = new MySpecialCollection();
IList list = (IList)myspecialcollection;
Рассматривали ли вы возможность реализации IMySpecialCollection ISerializable для сериализации?Поддержка нескольких типов коллекций кажется мне немного неправильной.Вы также можете рассмотреть возможность приведения вашего IList к IEnumerable для сериализации, поскольку IList просто обертывает IEnumerable и ICollection.
Другие советы
Это обман мой вопрос здесь
Подводя итог, если вы сделаете это, это решит проблему:
public Interface IMySpecialCollection : IList<MyObject>, IList
{
new MyObject this[int index];
...
}
К сожалению, вы не можете объявить два индексатора с одним и тем же списком параметров.Следующий абзац взят отсюда Руководство по программированию на C#. Использование индексаторов. Раздел «Примечания»:
Сигнатура индексатора состоит из количества и типов его формальных параметров.Он не включает тип индексатора или имена формальных параметров.Если вы объявляете более одного индексатора в одном классе, они должны иметь разные подписи.
Если вы хотите использовать второй индексатор, вам придется объявить другой набор параметров.
Измените свою общую реализацию на...
T IList<T>.this[int index] { get; set; }
Это явно говорит, что это такое.
List<T> подразумевает IList, поэтому использовать оба в одном классе — плохая идея.