tags:

views:

409

answers:

4

I'm using a Dictionary<int, MyType> in a class. That class implements a interface that requires an IList<MyType> to be returned. Is there a simple way to to cast the one to the other (without copying the entire thing)?

My current solution follows:

private IList<MyType> ConvertToList(Dictionary<int, MyType>.ValueCollection valueCollection)
{
    List<MyType> list = new List<MyType>();
    list.AddRange(valueCollection);
    return list;
}
A: 

You can use the constructor:

public IList<MyType> MyValues
{
    get { return new List<MyType>(myDictionary.Values); }
}

(Edited to remove an assertion I'm not 100% sure on.)

Anna Lear
+4  A: 

How about

Dictionary<int, MyType> dlist = new Dictionary<int, MyType>();
IList<MyType> list = new List<MyType>(dlist.Values);
astander
This still copies the collection.
SLaks
+4  A: 

You'll need to do a copy, but this is probably a good thing. In C# 2, your current code is almost the cleanest you can make. It would be improved by directly constructing your list off your values (List<MyType> list = new List<MyType>(valueCollection);), but a copy will still be required.

Using LINQ with C# 3, however, you would be able to do:

myDictionary.Values.ToList();

That being said, I would not (probably) try to avoid the copy. Returning a copy of your values tends to be safer, since it prevents the caller from causing problems if they attempt to modify your collection. By returning a copy, the caller can do list.Add(...) or list.Remove(...) without causing your class problems.


Edit: Given your comment below, if all you want is an IEnumerable<T> with a Count, you can just return ICollection<T>. This is directly implemented by ValueCollection, which means you can just return your dictionary's values directly, with no copying:

private ICollection<MyType> ConvertToList(Dictionary<int, MyType>.ValueCollection valueCollection)
{
    return valueCollection;
}

(Granted, this method becomes really useless in this case - but I wanted to demonstrate it for you...)

Reed Copsey
@Slaks: Hence the next sentence: "You can directly construct your list off your values," ;) That's not much better, although since it's an ICollection<T>, it will be more efficient (since count is known in advance).
Reed Copsey
@Slaks: That better? I made it more explicit.
Reed Copsey
Thanks for the excellent answer. The ICollection interface fit my needs perfectly.
C. Ross
+1  A: 

This is not possible.

A dictionary (including its Values collection) is an inherently unordered collections; its order will change based on the hashcodes of its keys. This is why ValueCollection doesn't implement IList<T> in the first place.

If you really wanted to, you could make a wrapper class that implements IList and wraps the ValueCollection, using a foreach loop in the indexer. However, it's not a good idea.

SLaks
@SLaks I'm not picky about the order. What I want is IEnumerable with a count. If there's a better Interface, let me know.
C. Ross
@C. Ross: See my edit, then...
Reed Copsey