Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does string not implement IList<char>?

Tags:

string

c#

.net

Title says all

Why does String implement IEnumerable<char> and not IList<char>?

A string has a length and you can already take elements from a specific index.
And it could be indicated that it is immutable with ICollection<char>.IsReadOnly.

So what could be wrong with it? Am I missing something?

As many answers point on that: There is not an interface for read only lists/collections alone, but as ReadOnlyCollection<T> shows I think its definitely possible and with it's IsReadOnly Property designed for such cases.

   public class String : IList<char>
    {
        int IList<char>.IndexOf(char item)
        {
            // ...
        }

        void IList<char>.Insert(int index, char item)
        {
            throw new NotSupportedException();
        }

        void IList<char>.RemoveAt(int index)
        {
            throw new NotSupportedException();
        }

        char IList<char>.this[int index]
        {
            set
            {
                throw new NotSupportedException();
            }
        }

        void ICollection<char>.Add(char item)
        {
            throw new NotSupportedException();
        }

        void ICollection<char>.Clear()
        {
            throw new NotSupportedException();
        }

        public bool Contains(char item)
        {
            // ...
        }

        public void CopyTo(char[] array, int arrayIndex)
        {
            // ...
        }

        int ICollection<char>.Count
        {
            get { return this.Length; }
        }

        public bool IsReadOnly
        {
            get { return true; }
        }

        bool ICollection<char>.Remove(char item)
        {
            throw new NotSupportedException();
        }

        // ...
    }
like image 252
ordag Avatar asked Aug 20 '11 23:08

ordag


People also ask

How do I initialize an IList?

IList<ListItem> allFaqs = new List<ListItem>(); and it should compile. You'll obviously have to change the rest of your code to suit too. IList<ListItem> test = new ListItem[5]; IList<ListItem> test = new ObservableCollection<ListItem>(allFaqs);

Does array implement IList?

Definition of IList interface is "Represents a non-generic collection of objects that can be individually accessed by index.". Array completely satisfies this definition, so must implement the interface.

Why do we use IList in C#?

The IList interface implemented from two interfaces and they are ICollection and IEnumerable. List and IList are used to denote a set of objects. They can store objects of integers, strings, etc. There are methods to insert, remove elements, search and sort elements of a List or IList.

Should I use IList or IEnumerable?

You should use IList when you need access by index to your collection, add and delete elements, etc., and IEnumerable when you need just enumerate over your collection.


2 Answers

Mainly because IList inherits from ICollection, and strings do not support the mutable beahviors ICollection promises (add, remove, & clear) - when you add or remove character elements from a string, it creates a new string.


Implementing part of an interface is bad design. You might do it sometimes out of necessity, but it's never a good choice. It's better to split the interface. (The .NET collection interfaces should probably have been split to segregate the mutable members from the diagnostic ones.) Meta-functions like IsReadOnly make the interface less coherent and make it harder to use.

So even though a string is in many respects a list - you can index a string and find the count of characters in it - it's pretty rare that someone's actually going to want to treat a string like an IList<char>, especially in a post-3.5-world when there are simple transformations available that make it easy to get this information from an IEnumerable<char>.

like image 53
Jeff Sternal Avatar answered Oct 08 '22 13:10

Jeff Sternal


The fact that ReadOnlyCollection supports IList is in my opinion highly: meh.

IList is a contract that indicates that implementers support collection mutation (e.g. Add, Remove, Insert) which on an immutable object is clearly wrong. Carrying this over to System.String is just plain wrong as it is also immutable by design.

System.String implementing IList would be a terrible API design as a bunch of the methods would not work, so strings would not work in the same way as types that fully implement IList.

Perhaps you are hopping that it supported a more liberal interface, sure, but IList is not the right choice.

Partial interface implementation like this breaks the Liskov substitution principle, and introduces potential runtime bugs.

Update

Interestingly enough, .Net 4.5 introduces the new IReadOnlyList interface. However, String does not implement it, and it could not be introduced into the IList hierarchy.

Some background: http://www.infoq.com/news/2011/10/ReadOnly-WInRT.

like image 35
Tim Lloyd Avatar answered Oct 08 '22 11:10

Tim Lloyd