2008-09-11 7 views
7

У меня есть коллекция, которая реализует интерфейс, который расширяет как IList < T>, так и List.Как решить двусмысленность вызова между Generic.IList <T> .this [] и IList.this []?

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 ...

+0

Могу ли я спросить, как вы сериализации пользовательских индексатор? Когда я пытался индексировать пользовательский индекс (для WCF), я получаю сообщение с желтым экраном ASP, в котором говорится, что пользовательские индексы не могут быть сериализованы. В конце концов я просто отказался от этой идеи. –

ответ

3

Вы не можете сделать это с

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

Но вы можете делать то, что вы хотите с классом, вам нужно будет сделать для реализации одного из интерфейсов явных. В моем примере я сделал IList явным.

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

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

Вы рассматривали возможность IMySpecialCollection реализации ISerializable для сериализации? Поддержка нескольких типов коллекций кажется мне немного неправильной. Вы также можете посмотреть на листинг yout IList на IEnumerable для сериализации, поскольку IList просто обертывает IEnumerable и ICollection.

+1

+1, заметив, что эта ошибка возникает при использовании интерфейса, но не класса. 0 для ISerializable + Xaml: P – Lucas

-1

Список < T> подразумевает IList, так что это плохо идея использовать оба в одном классе.

+1

IList не реализует IList. И мне нужно реализовать IList для целей сериализации. – Will

1

К сожалению, вы не можете объявить два индексатора с тем же списком параметров. Нижеприведенный абзац взят отсюда C# Programming Guide - Using Indexers "Remarks" section:

Подпись индексатора состоит из числа и типов его формальных параметров. Он не включает тип индексатора или имена формальных параметров. Если вы объявляете более одного индексатора в одном классе, они должны иметь разные подписи.

Вам нужно будет указать другой набор параметров, если вы хотите использовать второй индекс.

+1

У вас не может быть 2 указателя 'this', но вы можете иметь 'string IDataErrorInfo.this' и 'T IList .this'. Вам нужно будет передать объект перед доступом к индексу, но он работает. –

-1

Изменить общую реализацию для ...

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

Это явно говорит, который 'это' есть что.

+0

, оба из которых реализованы явно, вам нужно указать список, чтобы использовать один, который не то, что он хочет. он хочет по умолчанию использовать общий и скрывать не общий. – Lucas

2

Это контратип my question here

Итак, если вы сделаете это, он решает эту проблему:

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