4

I have noticed that array, in c#, implements ICollection<T>. How can an array implement a generic container interface, yet not be generic itself? Is it possible for us to do the same?

Edit: I would also like to know how the array is not generic, yet it accepts any type and has type safety.

public class ListOfStrings : IList<string>
{
...
}

This is a great example that demonstrates that we can create non-generics from a generic (Thank you MarcinJuraszek!!). This collection would be stuck with strings. My guess is that it has nothing to do with the generic value type declaration of string and is some internal wiring that I am unfamiliar with.

Thank you again!

sujith karivelil
  • 28,671
  • 6
  • 55
  • 88
Maderas
  • 231
  • 2
  • 14
  • 1
    Arrays are already generic - `int[]` defines an array of type `int`. Since it's an in-built type, I would imagine there is some syntactical sugar to essentially be `Array` (Note, though, that `Array` is different from `[]` - it's just an example) – Rob Mar 01 '16 at 03:21
  • That makes complete sense and that will really help me think of this in the future! int[] ~ Array – Maderas Mar 01 '16 at 03:24

1 Answers1

6

Yes, it's totally possible. You can declare something like this:

public class MyListOfStrings : IList<string>
{
}

and as long as you implement all the properties/methods IList<string> requires you to everything will work just fine. As you can see MyListOfStrings is not generic.

You should also remember that Arrays are special types, and there is a bunch of stuff going on with them that's not happening with regular user-defined types. Some of it is described on MSDN, and the part that seem to be related to your questions is here:

Starting with the .NET Framework 2.0, the Array class implements the System.Collections.Generic.IList<T>, System.Collections.Generic.ICollection<T>, and System.Collections.Generic.IEnumerable<T> generic interfaces. The implementations are provided to arrays at run time, and as a result, the generic interfaces do not appear in the declaration syntax for the Array class. In addition, there are no reference topics for interface members that are accessible only by casting an array to the generic interface type (explicit interface implementations). The key thing to be aware of when you cast an array to one of these interfaces is that members which add, insert, or remove elements throw NotSupportedException.

As you can see Array implements IList<T>, ICollection<T> and IEnumerable<T> in a special way, and it's not something you can do with your own type.

MarcinJuraszek
  • 124,003
  • 15
  • 196
  • 263
  • 1
    I am unfamiliar with the etiquette here. I would like to clarify something in my question but I don't want it to to seem as if you didn't answer my question. Do I just make the edit or do I ask here? It is a question regarding the idea that an array accepts any type but your MyListOfStrings would only accept strings. How did they make the array non-generic but accept any type? Thanks for the edit, btw. – Maderas Mar 01 '16 at 03:14
  • 1
    Feel free to update your question with that clarification. – MarcinJuraszek Mar 01 '16 at 03:14
  • 1
    @RyanWoods In general, if the edit invalidates existing answers, it's probably best to either clarify in the comments (assuming it's a minor change), or post a new question. Be aware though, that continually clarifying the question in comments is looked down upon - and at that point should probably be a new question. – Rob Mar 01 '16 at 03:17
  • Am I missing something, or does array not just implement the non-generic version or IList, ICollection, etc in 4.6.1? http://referencesource.microsoft.com/#mscorlib/system/array.cs – Simon C Mar 01 '16 at 03:25
  • Thank you for the answer. I will take a look at the MSDN first next time. I will say that I would not have gleaned this information from the MSDN as well as you did. Your explanation gives it more sense. Between you, MarcinJuraszek, and Rob, I have a much better understanding of this topic. Thank you. – Maderas Mar 01 '16 at 03:26
  • @SimonC Yes, `Array` (the class) only implements the non-generic version, but `int[]` implements `IList` – Rob Mar 01 '16 at 03:29
  • Hello Simon C, I pasted the msdn class signature for an array. You are right! `public abstract class Array : ICloneable, IList, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable` – Maderas Mar 01 '16 at 03:29
  • @Rob, so that's what the `SZArrayHelper` does at runtime? Complex! – Simon C Mar 01 '16 at 03:36