Home > Software engineering >  Generic method does not return values to dictionary
Generic method does not return values to dictionary

Time:10-19

I have some multiplied code which suppose to be easily merged under common method.

public void LoadApples(IEnumerable<Apple> apples)
    {
        _apples.Clear(); //_apples = List<Apple>
        _apples.AddRange(apples);
        ApplesId = _apples.ToDictionary(keySelector: m => m.Id, elementSelector: m => m); //ApplesId  = Dictionary<int, Apple>
    }

I have exactly same code for pears and oranges. Sounds like a good job for some generic method. So I wrote this:

public void LoadData<T>(IEnumerable<T> t, List<T> l, Dictionary<int, T> d) where T : IDatabaseValue 
//IDatabaseValue has fields int Id and string Name
    {
        l.Clear();
        l.AddRange(t);
        d = l.ToDictionary(keySelector: m => m.Id, elementSelector: m => m);
    }

List is filled fine with values from Enumerable. Dictionary is also filled with values, though it's not transfered into original dictionary. How to achieve that secret art of passing values from method? :/

Code to run that generic method is just

LoadData(apples, _apples, AppleId);

Both list and dictionary are declared earlier in the code.

CodePudding user response:

There's possibly a bit more to unpack here than just the comment from @Ralf. Just to be short: this seems like a crude design, e.g.:

  • why use an extra List when the Dictionary might suffice?
  • why not to use _apples = apples.ToList() also?

But back to the question. The immediate answer is the same as Ralf suggested:

change the method to:

public Dictionary<int, T> LoadData<T>(IEnumerable<T> t, List<T> l) where T : IDatabaseValue 
{
    l.Clear();
    l.AddRange(t);
    return l.ToDictionary(keySelector: m => m.Id, elementSelector: m => m);
}

and call it with AppleId = LoadData(apples, _apples);

Based on the fact that this lead you to ask on SO, I'd recommend studying the documentation a bit ;)

Another option would be: pass the Dictionary by reference

public void LoadData<T>(IEnumerable<T> t, List<T> l, ref Dictionary<int, T> d) where T : IDatabaseValue 
{
    l.Clear();
    l.AddRange(t);
    d = l.ToDictionary(keySelector: m => m.Id, elementSelector: m => m);
}
//------------
//with call
LoadData(apples, _apples, ref AppleId);

CodePudding user response:

Can Do like this

public Dictionary<int, T> LoadData<T>(IEnumerable<T> t, List<T> l) where T : IDatabaseValue 
//IDatabaseValue has fields int Id and string Name
    {
        l.Clear();
        l.AddRange(t);
        return l.ToDictionary(keySelector: m => m.Id, elementSelector: m => m);
    }

Change code where your calling this method

ApplesId = LoadData<Apple>(apples,_apples);
  • Related