重构将NameValueCollection和KeyValueConfigurationCollection作为参数?

时间:2010-08-24 06:42:48

标签: c# .net refactoring .net-2.0

示例代码:

已编辑:澄清示例。对不起任何困惑。

        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
        }
    }

目前有两个版本的DoSomethingWithCollection可以采用NameValueCollection或KeyValueConfigurationCollection。

是否有更简洁的方法来执行此操作,因此只有一个版本的DoSomethingWithCollection?

感谢。

3 个答案:

答案 0 :(得分:4)

好吧,DoSomethingWithCollection应该接受两个参数 - 1)ICollection / IEnumerable,它允许你枚举所有的值2)委托将获取对象并给你键和值。因此,您需要基本上编写两种不同的方法来解析两种类型的集合的项目。

编辑:提供想法的示例代码。

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
   }
}

编辑 2:不确定你不需要委托是什么意思 - 如果你需要有一个版本的DoSomethingWithCollection,你需要至少有一些代码在两个集合中都有不同的作用。代表是最简单的方式。另一种方法是定义一个接口,该接口将提供NamedValuePair / KeyValuePair的集合/枚举,然后写入为不同类型的目标集合实现此接口的包装类。模板代码将是

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,对于一个简单的要求来说太多了。

答案 1 :(得分:1)

您可以编写两个DoSomethingWithCollection重载,一个采用NameValueCollection,另一个采用KeyValueConfigurationCollection。然后,每个重载都会迭代集合,将键和值传递给第三个执行任何操作的方法。

答案 2 :(得分:0)

只要集合NameValueCollectionKeyValueConfigurationCollection同时实现了ICollectionIEnumerable,您就可以做下一步:

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
    }
}