7

I've got a collection that implements an interface that extends both IList<T> and List.

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

That means I have two versions of the indexer.

I wish the generic implementation to be used, so I implement that one normally:

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

I only need the IList version for serialization, so I implement it explicitly, to keep it hidden:

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

However, in my unit tests, the following

MyObject foo = target[0];

results in a compiler error

The call is ambiguous between the following methods or properties

I'm a bit surprised at this; I believe I've done it before and it works fine. What am I missing here? How can I get IList<T> and IList to coexist within the same interface?

Edit IList<T> does not implement IList, and I must implement IList for serialization. I'm not interested in workarounds, I want to know what I'm missing.

Edit again: I've had to drop IList from the interface and move it on my class. I don't want to do this, as classes that implement the interface are eventually going to be serialized to Xaml, which requires collections to implement IDictionary or IList...

Luigi
  • 4,129
  • 6
  • 37
  • 57
  • May I ask how you're serializing a custom indexer? When I've tried to index a custom indexer (for WCF), I get an ASP yellow-screen-of-death message saying that custom indexers cannot be serialized. I eventually just gave up on the idea. – Jarrett Meyer Sep 11 '08 at 17:10

5 Answers5

3

You can't do this with

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

But you can do what you want with a class, you will need to make the implementations for one of the interfaces explicit. In my example I made IList explicit.

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

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

Have you considered having IMySpecialCollection implement ISerializable for serialization? Supporting multiple collection types seems a bit wrong to me. You may also want to look at casting yout IList to IEnumerable for serialization since IList just wraps IEnumerable and ICollection.

Darryl Braaten
  • 5,229
  • 4
  • 36
  • 50
  • 1
    +1 for noticing that this error occurs when using an interface but not a class. 0 for ISerializable + Xaml :P – Lucas Apr 29 '09 at 17:24
2

This is a dupe of my question here

To summarise, if you do this, it solves the problem:

public Interface IMySpecialCollection : IList<MyObject>, IList
{
    new MyObject this[int index];
    ... 
}
Community
  • 1
  • 1
Orion Edwards
  • 121,657
  • 64
  • 239
  • 328
1

Unfortunately you can't declare two indexers with the same parameter list. The following paragraph is taken from here C# Programming Guide - Using Indexers "Remarks" section:

The signature of an indexer consists of the number and types of its formal parameters. It does not include the indexer type or the names of the formal parameters. If you declare more than one indexer in the same class, they must have different signatures.

You will have to declare a different set of parameters if you wish to use the second indexer.

Adrian Clark
  • 12,449
  • 5
  • 36
  • 42
  • 1
    You can't have 2 indexers 'this', but you can have a 'string IDataErrorInfo.this' and a 'T IList.this'. You'll have to cast the object before accessing the indexer, but it works. – Jarrett Meyer Sep 11 '08 at 17:08
-1

Change your generic implementation to...

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

This explicitly says which 'this' is which.

Jarrett Meyer
  • 19,333
  • 6
  • 58
  • 52
  • with both implemented explicitly, you need to cast the list to use either one, which is not what he wants. he wants to default to the generic one and hide the non-generic one. – Lucas Apr 29 '09 at 17:22
-2

List<T> implies IList, so it's a bad idea to use both in the same class.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • 1
    IList does not implement IList. And I need to implement IList for serialization purposes. –  Sep 11 '08 at 16:48