views:

37

answers:

3

Example code :

EDITED : clarified example. Sorry for any confusion.

        using System.Collections.Specialized;
        using System.Configuration;

    ...

        // get collection 1

        NameValueCollection c1 = ConfigurationManager.AppSettings;

        // get collection 2

        ExeConfigurationFileMap map = new ExeConfigurationFileMap();
        map.ExeConfigFilename = "c:\\SomeConfigFile.config";
        Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
        KeyValueConfigurationCollection c2 = config.AppSettings.Settings;

        // do something with collections

        DoSomethingWithCollection(c1);
        DoSomethingWithCollection(c2);
...

    private void DoSomethingWithCollection(KeyValueConfigurationCollection c)
    {
        foreach(KeyValueConfigurationElement el in c)
        {
            string key = el.Key;
            string val = el.Value;
            // do something with key and value
        }
    }

    private void DoSomethingWithCollection(NameValueCollection c)
    {
        for(int i=0; i < c.Count; i++)
        {
            string key = c.GetKey(i);
            string val = c.Get(i);
            // do something with key and value
        }
    }

There are currently two versions of DoSomethingWithCollection to take either a NameValueCollection or KeyValueConfigurationCollection.

Is there a cleaner way of doing this, so that there is just one version of DoSomethingWithCollection ?

Thanks.

+4  A: 

Well, DoSomethingWithCollection should accept two parameters - 1) ICollection/IEnumerable that will allow you to enumerate through all values 2) Delegate that will take the object and give you key and value back. So you need to essentially write two different methods to parse the item for both type of collections.

Edit: A sample code to give an idea.

delegate void KeyValueItemParser(object item, out string key, out string value);

void DoSomethingWithCollection(ICollection items, KeyValueItemParser parser)
{

   string key, value
   foreach(object item in items)
   {
      parser(item, out key, out value);
      // do whatever you want to with key & value
   }
}

Edit 2: Not sure what you mean by not needing a delegate - if you need to have one version of DoSomethingWithCollection, you need to have at least some code that work different across both collection. Delegate would be the simplest way. Another way would be define an interface that will provide a collection/enumeration of NamedValuePair/KeyValuePair and then write to wrapper classes implementing this interface for different kind of target collections. Template code would be

interface IKeyValuePairCollection
{
  int Count {get; }
  KeyValuePair<string, string> Item(int index) { get; }
}

class NamedValueCollectionWrapper : IKeyValuePairCollection
{

   private NamedValueCollection _inner;

   public NamedValueCollectionWrapper(NamedValueCollection target) 
   {
     -inner = target;
   }

   // roll out ur implementation to IKeyValuePairCollection
}

class KeyValueConfigurationCollectionWrapper : IKeyValuePairCollection
{
  ...
}

IMO, a too much work for a simple requirement.

VinayC
I removed the "not needing a delegate" part in my edit - I had misunderstood what you were trying to do. From replies here, it does look like there is not enough in common between the two types to do a simple solution. But thanks for the effort.
Moe Sisko
+1  A: 

You could write two overloads of DoSomethingWithCollection, one that takes a NameValueCollection and another that takes a KeyValueConfigurationCollection. Then, each of those overloads iterates over the collection, passing the key and value to a third method that performs whatever you want to do.

+1  A: 

As far as both collections NameValueCollection and KeyValueConfigurationCollection implements both ICollection and IEnumerable you can do next:

private void DoSomethingWithCollection(ICollection collection)
// private void DoSomethingWithCollection(IEnumerable collection)
{
    NameValueCollection nv;
    KeyValueConfigurationCollection kvc;
    if ((nv = collection as NameValueCollection) != null)
    {
        // do stuff directly or call iterate and call 3rd method
    }
    else if ((kvc = collection as KeyValueConfigurationCollection) != null)
    {
        // do stuff directly or call iterate and call 3rd method
    }
}
abatishchev