4

Suppose I have an ICollection<SomeClass>.

I have the following two variables:

SomeClass old;
SomeClass new;

How can I achieve something like the following using an ICollection<SomeClass>?

// old is guaranteed to be inside collection
collection.Replace(old, new);
Dariusz Woźniak
  • 9,640
  • 6
  • 60
  • 73
Matias Cicero
  • 25,439
  • 13
  • 82
  • 154

3 Answers3

8

There is no black magic here: ICollection<T> is not ordered and only provides Add/Remove methods. Your only solution would be to check if the actual implementation is something more, such as IList<T>:

public static void Swap<T>(this ICollection<T> collection, T oldValue, T newValue)
{
    // In case the collection is ordered, we'll be able to preserve the order
    var collectionAsList = collection as IList<T>;
    if (collectionAsList != null)
    {
        var oldIndex = collectionAsList.IndexOf(oldValue);
        collectionAsList.RemoveAt(oldIndex);
        collectionAsList.Insert(oldIndex, newValue);
    }
    else
    {
        // No luck, so just remove then add
        collection.Remove(oldValue);
        collection.Add(newValue);
    }

}
ken2k
  • 48,145
  • 10
  • 116
  • 176
0

The ICollection<T> interface is quite limited, you will have to use Remove() and Add()

collection.Remove(old);
collection.Add(new);
Jakub Lortz
  • 14,616
  • 3
  • 25
  • 39
  • I thought about this, but `new` will be added to the end of the collection, instead of `old`'s location – Matias Cicero Dec 23 '15 at 12:36
  • 1
    Ya, that's why I removed my comment. But it would be more accurate to say `ICollection` is not guaranteed to have an order. For that you should be using something more specific that is common between all of your used collection types that actually supports order. Perhaps `IList` instead? – gmiley Dec 23 '15 at 12:39
  • @MatiasCicero, Even thought it has some order, it is only implementation detail and you shouldn't refer to it when you design your classes. – Hamlet Hakobyan Dec 23 '15 at 12:40
  • 1
    @MatiasCicero If you need an ordered collection, you should use `IList` – Jakub Lortz Dec 23 '15 at 12:42
  • @MatiasCicero You mentioned that you use `HashSet` as the `ICollection` implementation. Sets are by definition unordered. From MSDN HashSet doc: "A set is a collection that contains no duplicate elements, and whose elements are in no particular order." – Jakub Lortz Dec 23 '15 at 12:47
  • not always work, ie if you remove inside a foreach statement – Santiago Rebella Jun 06 '17 at 16:52
-1

Do that:

    yourCollection.ToList()[index] = newValue;