Coder Absolute Coder Absolute - 3 months ago 24
C# Question

Convert a generic IEnumerable<T> to IEnumerable<KeyValuePair> (C#)

In the following code, I need to explicitly mention

CountryId
and
CountryName
but I would like to avoid that and trying to create a
generic method
.

public struct KeyValueStruct
{
public int Key { get; set; }
public string Value { get; set; }
}

private static IEnumerable<KeyValueStruct> ConvertPocoToKeyValueList(IEnumerable<CountryPoco> list)
{
var result = new List<KeyValueStruct>();

if (list != null)
{
foreach (var item in list)
{
result.Add(new KeyValueStruct()
{
Key = item.CountryId,
Value = item.CountryName
});
}
}

return result;
}


I know from the list that first property is always integer (which is CountryId in this example) and second property would be String.

I was thinking to implement using
Generics
but am not sure is this the best approach, see my proposed code (it's not working though).

private static IEnumerable<KeyValueStruct> ConvertPocoToKeyValueList<T>(T list)
{
var result = new List<KeyValueStruct>();

if (list != null)
{
foreach (var item in list)
{
result.Add(new KeyValueStruct()
{
Key = item.CountryId,
Value = item.CountryName
});
}
}

return result;
}


If you have a better idea to achieve the same result, then please propose.

Answer

You can make that generic by passing the properties to be used as Key and value. I think using the generic struct named KeyValuePair<Tkey, TValue> is better than reinventing the wheel yourself:

private static IEnumerable<KeyValuePair<Tkey, TValue>> 
                       ConvertPocoToKeyValueList<TSource, Tkey, TValue>
                                    (IEnumerable<TSource> list,
                                     Func<TSource, Tkey> keySelector,
                                     Func<TSource, TValue> valueSelector)
        {
            return list.Select(item => new KeyValuePair<Tkey, TValue>
                                          (keySelector(item), valueSelector(item)));
        }

Usage:

var result = ConvertPocoToKeyValueList(list, x=> x.CountryId, x=> x.CountryName);

You can even do that without using this generic method by using directly:

var result = list.Select(item => new KeyValuePair<Tkey, TValue>
                                              (item.CountryId, item.CountryName));