5

I know the title could probably be a bit more descriptive/better phrased, but it was the best I could come up with.

Currently I have a class with a lot of methods looking like the ones below:

        private static void UpdateArtists()
        {
            artists.Clear();
            foreach (AudioInfo entry in library_entries)
            {
                artists.Add(entry.Artist, entry);
            }
        }

        private static void UpdateAlbums()
        {
            albums.Clear();
            foreach (AudioInfo entry in library_entries)
            {
                albums.Add(entry.Album, entry);
            }
        }

        private static void UpdateGenres()
        {
            genres.Clear();
            foreach (AudioInfo entry in library_entries)
            {
                genres.Add(entry.Genre, entry);
            }
        }

        private static void UpdateYears()
        {
            years.Clear();
            foreach (AudioInfo entry in library_entries)
            {
                years.Add(entry.Year, entry);
            }
        }

Needless to say, writing dozens of these is very tiresome. So I was wondering if it's possible to simplify it and make a method something like this:

     private static void Update(Dictionary<string, AudioInfo> dictionary, AudioInfo.Property property)
     {
         dictionary.Clear();
         foreach (AudioInfo entry in library_entries)
         {
             dictionary.Add(entry.property, entry);
         }
         //Where "property" is a property in the AudioInfo-class.
     }

Is that doable, and if it is; how?

Thanks!

Heidenreich
  • 61
  • 1
  • 4
  • Note that you don't need `ref` at all, classes are always passed by reference. – Julien Lebosquain Jul 10 '11 at 09:39
  • Heh, you're right of course. That's what you get when you sit up the entire night. – Heidenreich Jul 10 '11 at 09:42
  • possible duplicate of [How can I pass a property of a class as a parameter of a method?](http://stackoverflow.com/questions/1178574/how-can-i-pass-a-property-of-a-class-as-a-parameter-of-a-method) – nawfal Feb 11 '13 at 10:38

1 Answers1

15

It seems like you have some design errors in your class if you need to do such things. nevertheless, the solution is:

private static void Update(Dictionary<string, AudioInfo> dictionary, Func<AudioInfo, string> func)
{
    dictionary.Clear();
    foreach (AudioInfo entry in library_entries)
    {
        dictionary.Add(func(entry), entry);
    }
}

And the usage is:

Update(years, x => x.Year);

Also you can use easier way, instead of call any methods you can just write:

years = library_entries.ToDictionary(x => x.Year, x => x);

If you have not any events, linked with your dictionary.

And one more thing to go - you can't add different elements with the same keys to dictionary. In your case it seems like you have different AudioInfo objects with the same Year, Genre e.t.c.

oxilumin
  • 4,775
  • 2
  • 18
  • 25
  • 1
    You don't have to pass dictionary by `ref`. – Jalal Said Jul 10 '11 at 09:42
  • Yes, you are right, I just copied the signature from the question. – oxilumin Jul 10 '11 at 09:59
  • Actually I have a custom OneToManyDictionary, that has a list of items for each key. If I add a duplicate key, it adds the value to the list associated with the key. Thought I'd simplify my question and just use a regular Dictionary to avoid more confusion than needed :d. That being said, guess I'll go with the Func version. Thanks! – Heidenreich Jul 10 '11 at 10:07
  • I'm genuinely curious what the design errors are in this case. My code could really benefit from such a critique. What are the errors and how could they be fixed? – kdbanman Aug 19 '15 at 19:07