0

The .Net class ArrayList has the Add method which has the below 2 overloads.

int Add(System.Object value)
int IList.Add(System.Object value)

I understand the first signature and as I understand it, the IList above refers to an interface but could you please explain what it really means? How can I use it in a simple C# program? Thanks.

Steve
  • 337
  • 4
  • 11
  • 2
    Those are not overloads, they're the same method. `IList` declares this method, `ArrayList` implements it. – Jeroen Mostert Apr 04 '22 at 10:44
  • 2
    Hold on. **Stop**. Why are you using `ArrayList` in the first place? **There is no legitimate reason for using `ArrayList` today**. – Dai Apr 04 '22 at 10:44
  • The question was purely academic to understand the subject in depth. – Steve Apr 04 '22 at 10:45
  • 1
    using an ArrayList is a very bad idea, use List or List instead.... – J.Salas Apr 04 '22 at 10:46
  • 1
    The `int IList.Add(Object)` method in `ArrayList` is an **explicit interface implementation** of the `IList.Add` method (and I've closed this question as a dupe of a question asking about explicit implementations). However, **no-one should be using either `ArrayList` _nor_ `IList` today**. They are relics of the _time before generics_ (2001-2005) and should be forgotten. – Dai Apr 04 '22 at 10:47
  • @Dai, recently bought C# in depth. Why does the author go in to detail the features of C#1? – Steve Apr 04 '22 at 10:48
  • @Steve Because you bought a book that's _out of date_. – Dai Apr 04 '22 at 10:48
  • @Dai - I mainly use PowerShell where Arraylist is very useful for simple use cases. Using Generic collections unnecessary complicates the code for System Administrators. – Steve Apr 04 '22 at 10:49
  • @Steve [PowerShell has its own built-in collection types you should use instead](https://www.red-gate.com/simple-talk/sysadmin/powershell/powershell-one-liners--collections,-hashtables,-arrays-and-strings/) of _obsolete_ .NET Framework types. – Dai Apr 04 '22 at 10:50
  • @Dai - you have answered my question - Now I understood - it's the explicit interface implementation for the Add method. Thanks. – Steve Apr 04 '22 at 10:51
  • @Dai - Arraylist is simple and convenient to use a list that grows and shrinks with very little code and easier to understand. Are you aware of any better built in PowerShell alternative? – Steve Apr 04 '22 at 10:52
  • @Steve You are mistaken: `ArrayList` **does not automatically shrink**, and PowerShell's built-in array type is dynamically sized. See the page I linked to. – Dai Apr 04 '22 at 10:54
  • @Dai: that is not the case. `ArrayList` implements `IList.Add` the regular way (by providing a `public` method matching the signature). There is *no* explicit interface implementation here (despite what the OP's GUI may show), and so the duplicate isn't right either. – Jeroen Mostert Apr 04 '22 at 10:54
  • @JeroenMostert Well, _this is embarrassing_... – Dai Apr 04 '22 at 10:55
  • I didn't mean automatically shrink (sorry). What I wanted to say was add and remove items easily – Steve Apr 04 '22 at 10:57
  • @JeroenMostert I bite my thumb at the arbitrary 5-minute StackOverflow lockout for editing one's own comments, argh. – Dai Apr 04 '22 at 10:57
  • @Steve On the contrary, because `ArrayList.Remove` uses `Object.Equals(Object)` (via `ArrayList.IndexOf`) it actually _makes it harder_ to remove items (when those items override `Equals`), depending on the equality behaviour you're after (as the `IndexOf` and `Remove` methods do not allow you specify your own `IEqualityComparer`), which is yet another reason why `ArrayList` should be consigned to the dustbin of history). – Dai Apr 04 '22 at 11:00
  • @Dai: _"nor `IList`"_ - this is not entirely true. Even generic collections are encouraged to implement non-generic interfaces so serializers can populate them easily. Otherwise you could not add elements to it without using reflection. – György Kőszeg Apr 04 '22 at 11:01
  • @GyörgyKőszeg re: "generic collections are encouraged to implement non-generic interfaces" - Citation? Remember that `IReadOnlyList` is a covariant interface (over `out T`), so that shouldn't be necessary. – Dai Apr 04 '22 at 11:01
  • @JeroenMostert I use the below technique in Poweshell to find out the method signatures [System.Collections.ArrayList]::new().Add – Steve Apr 04 '22 at 11:03
  • As for `ArrayList`, I mainly agree that it should not be used. Though ironically everyone has to deal with it who handles `ObservableCollection` events in WPF because `NotifyCollectionChangedEventArgs` members are always populated with `ArrayList` instances – György Kőszeg Apr 04 '22 at 11:03
  • @Dai: _"Remember that IReadOnlyList is a covariant interface (over out T), so that shouldn't be necessary."_ - I don't know how is it relevant when you want to populate a list of any element type instantiated by the deserializer. – György Kőszeg Apr 04 '22 at 11:07
  • @GyörgyKőszeg It's relevant because it means _any_ `IReadOnlyList` (including `List`) can be coirrectly downcasted to `IEnumerable` (as `T` to `Object` is covariant), which is why serializers can use generic collection interfaces without needing them to implement the non-generic `IList` interface (though this is only valid when `T : class`), but handling `T : struct` isn't much extra work, honestly). – Dai Apr 04 '22 at 11:08
  • 2
    @Steve: unfortunately PowerShell is being unnecessarily misleading here by showing these definitions as though they were separate methods (`Get-Member` does the same thing). This is definitely not the case. Implementations of interface methods are not overloads as such. Neither this approach nor `Get-Member` make an effort to distinguish between explicit or implicit implementations and will simply list all interface entries separately from the class methods. – Jeroen Mostert Apr 04 '22 at 11:10
  • @JeroenMostert You are entirely correct there, +1 – Dai Apr 04 '22 at 11:13
  • 1
    To see an explicit interface implementation, try `[System.Collections.Generic.List[string]]::new().Add`. The list will include `int IList.Add(System.Object value)`, which *is* an explicit implementation, with a signature that's different from the other `Add`s (taking `object` rather than `string`). This is still not an overload, though in PowerShell it would be hard to see the difference due to its easy attitude to implicit conversions. – Jeroen Mostert Apr 04 '22 at 11:14
  • @Dai: Please do understand what I'm talking about. Generic `IReadOnlyList` does not help you to populate a list of an unknown element type (on deserialization). And variance is not needed to access its elements when _reading_ the collection (on serialization). It just works even in pre C# 4.0 (before interface covariance was introduced) because all collections implement also the non-generic `IEnumerable` interface. – György Kőszeg Apr 04 '22 at 11:47

0 Answers0