user2047824
user2047824

Reputation: 723

return IDictionary<string, ICollection<ValueSet>>

I'm trying to return interface IDictionary (with string key and List values) like:

IDictionary<string, ICollection<ValueSet>> method( ...) {

}

From inside of the method I create the Dictionary object:

var dic = new Dictionary <string, List <ValueSet> >();

Everything works well, but I can't return the dic object here. I cannot implicitly convert.

How can I make this thing work?

public IDictionary < string, ICollection < ValueSet > > GetValueSets(ICollection < string > contentSetGuids)

{
    var dic = new Dictionary < string, List < ValueSet > > ();

    using (SqlCommand command = new SqlCommand())
    {
        StringBuilder sb = new StringBuilder(ValueSet.ValueSetQueryText);
        sb.Append(" where contentsetguid ");
        sb.Append(CreateInClause(contentSetGuids));

        command.CommandText = sb.ToString();

        dic = GetObjects(command).GroupBy(vs => vs.ContentSetGuid).ToDictionary(grp => grp.Key, grp => grp.ToList());

    }

    return dic;
}

Error: Error 46 Cannot implicitly convert type 'System.Collections.Generic.IDictionary>' to 'System.Collections.Generic.IDictionary>'. An explicit conversion exists (are you missing a cast?)

Upvotes: 1

Views: 1691

Answers (2)

Stefan Steinegger
Stefan Steinegger

Reputation: 64658

I would consider changing the interface to somewhat more flexible:

IEnumerable<KeyValuePair<string, IEnumerable<ValueSet>> GetValueSets(
    IEnumerable<ValueSet> contentSetGuids)

{
    // ....
    return GetObjects(command)
        .GroupBy(vs => vs.ContentSetGuid)
        .Select(new KeyValuePair<string, IEnumerable<ValueSet>>(grp.Key, grp.ToArray())
}

Let the caller create a dictionary, it it requires one.

normally I would pass the string (the key) as argument and return only one element at once. But in the method, you get the whole data at once, so this doesn't make much sense.

Upvotes: 0

Daniel A.A. Pelsmaeker
Daniel A.A. Pelsmaeker

Reputation: 50376

You cannot cast a IDictionary<String, List<ValueSet>> to a IDictionary<String, ICollection<ValueSet>> because IDictionary<TKey, TValue> is not covariant. For example, the IEnumerable<T> interface is covariant, so you could cast IEnumerable<List<ValueSet>> to IEnumerable<ICollection<ValueSet>> if you wanted.

However, you can solve your problem somewhat by creating a dictionary of the correct type in your method. For example:

public IDictionary<string, ICollection<ValueSet>> GetValueSets(
    ICollection<ValueSet> contentSetGuids)
{
    var dic = new Dictionary<string, ICollection<ValueSet>>();   // <--

    using (SqlCommand command = new SqlCommand())
    {
        // ...
        dic = GetObjects(command)
              .GroupBy(vs => vs.ContentSetGuid)
              .ToDictionary(
                  grp => grp.Key,
                  grp => (ICollection<ValueSet>)grp.ToList());   // <--
    }

    return dic;
}

Upvotes: 2

Related Questions