Search code examples
c#linqactionfunc

How to run delegate based on dictionary (C#)


I have Mock class with below:

private readonly List<SomeObject> m_objectsList = new List<SomeObject>();

public Task<IList<Auto>> Todo(SomeParams params)
{
 IEnumerable<Auto> matches = m_objectsList.Select(GetMyObject);
 return Task.FromResult<IList<Auto>>(matches.ToArray());
}

private Auto GetMyObject(SomeObject s)
{
 Auto newAuto = new Auto
 {
     Id = s.Id,
     Name = s.Name,
 };    
 return newAuto;
}

This is working OK. Now I want to do like:

private readonly Dictionary<SomeObject, SomeParams> m_objectsList2 = 
                                                 new Dictionary<SomeObject, SomeParams>();

public Task<IList<Auto>> Todo2(SomeParams params)
{
 IEnumerable<Auto> matches = m_objectsList2.Select(GetMyObject2);
 return Task.FromResult<IList<Auto>>(matches.ToArray());
}

private Auto GetMyObject2(SomeObject s, SomeParams p)
 {
  Auto newAuto = new Auto();
     ....//some code
     return newAuto;
 }

but getting Compiler Error CS0411.


Solution

  • Dictionary<TKey, TValue> implements IEnumerable<KeyValuePair<TKey, TValue>>, and compiler can't perform method group conversion to delegate due to type mismatch. Either switch from using method group to lambda:

    IEnumerable<Auto> matches = m_objectsList2.Select(kvp => GetMyObject2(kvp.Key, kvp.Value));
    

    Or change signature of the method (or add an overload):

    private Auto GetMyObject2(KeyValuePair<SomeObject, SomeParams> kvp)
    {
         var (s, p) = kvp; // use deconstruction
         // or for older compilers/framework versions
         // var s = kvp.Key;
         // var p = kvp.Value;
         Auto newAuto = new Auto();
         ....//some code
         return newAuto;
    }