views:

81

answers:

2

Is there a way to cast a dictionary i a one-liner and without all the overhead in C# .net 3?

var result = new Dictionary<string, AccessoryVariant>();
foreach (BaseVariant variant in mVariants.Values)
{
    result.Add(variant.Id, (AccessoryVariant)variant);
}
return result;

I would like to do something like this:

return (Dictionary<string, AccessoryVariant>)mVariants;

/Sven

+6  A: 

Assuming you're using .NET 3.5 or 4, you can use the ToDictionary method in LINQ:

return mVariants.Values.ToDictionary(v => v.Id, v => (AccessoryVariant) v);

Alternatively:

return mVariants.Values.Cast<AccessoryVariant>().ToDictionary(v => v.Id);

Or (assuming mVariants is already using the Id as the key):

return mVariants.ToDictionary(pair => pair.Key,
                              pair => (AccessoryVariant) pair.Value);

Note that you can't cast the dictionary directly, because assuming mVariant is a Dictionary<string, BaseVariant>, someone could add a non-AccessoryVariant to the dictionary as a value, which would clearly mess up any code which (reasonably) assumed that the Dictionary<string, AccessoryVariant> only contained AccessoryVariant values.

Jon Skeet
+1, faster as always :-)
Darin Dimitrov
A: 

There is no way to cast to a dictionary of standard type since you can't add an explicit operator to it. But you can cast to a dictionary of your own type like this:

class Program
{
    static void Main(string[] args)
    {
        var list = new List<Entity<string>>()
        {
            new Entity<string>("1", "Some data 1"),
            new Entity<string>("2", "Some data 2")
        };

        var myCollection = (MyDictionary<string, Entity<string>>)list;
    }
}

public class Entity<T> : IId<T>
{
    private readonly T id;
    private string data;

    public Entity(T id, string data)
    {
        this.id = id;
        this.data = data;
    }

    public T Id
    {
        get { return id; }
    }

    public string Data
    {
        get { return data; }
        set { data = value; }
    }
}

public interface IId<T>
{
    T Id { get; }
}

public class MyDictionary<TKey, TValue>
    where TValue : IId<TKey>
{
    private readonly Dictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>();

    public void Add(TKey key, TValue value)
    {
        dictionary.Add(key, value);
    }

    public bool Remove(TKey key)
    {
        var wasActuallyRemoved = dictionary.Remove(key);

        return wasActuallyRemoved;
    }

    public bool TryGetValue(TKey key, out TValue value)
    {
        var wasSuccessfull = dictionary.TryGetValue(key, out value);

        return wasSuccessfull;
    }

    public static explicit operator MyDictionary<TKey, TValue>(List<TValue> items)
    {
        var myDictionary = new MyDictionary<TKey, TValue>();

        foreach (var item in items)
        {
            myDictionary.Add(item.Id, item);
        }

        return myDictionary;
    }
}

This is the answer to your question, though the approach with LINQ usage is better.

bsnote