可以从NameObjectCollectionBase派生的不同对象中提取值的单个方法?

时间:2016-01-18 19:33:18

标签: c# collections key-value

我正在使用源自NameObjectCollectionBase的多个集合。有没有办法从单个方法中从NameObjectCollectionBase派生的类中提取键/值对?

我可以在集合中获取密钥,但我无法获取值。到目前为止,我已经尝试过同时接受NameObjectCollectionBaseIEnumerable<object>的方法:

private void Test1(NameObjectCollectionBase coll) {
    foreach(var key in coll) {
        var value = coll[key]; //doesn't work
    }
}
//Produces this error:
//Cannot apply indexing with [] to an expression of type 'System.Collections.Specialized.NameObjectCollectionBase'

private void Test2(IEnumerable<object> coll) {
    foreach(var key in coll) {
        var value = coll[key]; //doesn't work
    }
}
//Produces this error:
//Cannot apply indexing with [] to an expression of type 'System.Generic.Collections.IEnumerable<object>'

我看到NameObjectCollectionBase具有从底层集合中检索项目的方法,但这些方法对于我在方法中收到的对象是受保护的。

编辑:提取方法不必通过括号。我一直在寻找任何方式来做这件事。

2 个答案:

答案 0 :(得分:1)

NameObjectCollectionBase不会为括号提供重载(据我在文档中看到)。据我所知,如果您需要,它可以为您提供括号的实现。

看一下这个例子:

  public Object this[ String key ]  {
      get  {
         return( this.BaseGet( key ) );
      }
      set  {
         this.BaseSet( key, value );
      }
  }

MSDN

我建议在这种情况下使用Dictionary<string, string>NameValueCollection,因为它具有您正在寻找的功能。它看起来并不像NameObjectCollectionBase在您的情况下提供任何有用的公共方法。

此外,您无法通过括号访问IEnumerable<T>。您只能使用ElementAt(int)获取元素。

答案 1 :(得分:0)

嗯,经过更多实验,我终于确定了一个T4模板。虽然,诚然,毕竟,我不得不同意任何人说只要有一种方法来处理每个不同的容器就会更容易。

反正。基本上,此模板提取NameObjectCollectionBase的所有公共子项,它们具有Get(字符串)方法签名和字符串或对象返回类型,然后为每个匹配的类标记一个Convert方法。

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.Collections.Specialized" #>
<#@ import namespace="System.Web" #>
<#@ output extension=".cs" #>
using System;
using System.Linq;
using System.Collections.Generic;
<#
//exclusions that don't return a value from Get(string) method.
//var exclusions = new List<string> { "HttpCookieCollection" };
var types = GetAllSubTypesOf(typeof(NameObjectCollectionBase));//.Where(t=>!exclusions.Contains(t.Name));
foreach (var type in types.GroupBy(t => t.Namespace).Select(t => t.FirstOrDefault())) {
    var ns = type.Namespace;
#>
using <#= ns #>;
<#
}
#>

namespace SomeNamespace {
public class NameObjectCollectionBaseConverter {
<#
    foreach(var type in types) {
        var argType = type.Name;
    #>
    public static Dictionary<string, string> Convert(<#= argType #> coll) {
        var keyValues = new Dictionary<string, string>();
        var keys = coll.Keys;
        foreach(var key in keys) {
            var strKey = key.ToString();
            var value = coll.Get(strKey).ToString();
            keyValues.Add(strKey, value);
        }

        return keyValues;
    }
    <#
    }
#>  
}
}
<#+
public static IEnumerable<Type> GetAllSubTypesOf(Type parent)
{
    foreach (var a in AppDomain.CurrentDomain.GetAssemblies()) { 
        foreach (var t in a.GetTypes()) {
            var methodInfo = t.GetMethod("Get", new [] { typeof(string) });

            if (
                t.IsSubclassOf(parent)
                && t.IsPublic
                && methodInfo != null
                && (
                    methodInfo.ReturnType == typeof(string)
                    || methodInfo.ReturnType == typeof(object)
                )
            ) {
                yield return t;
            }
        }
    }
}
#>

模板的输出是:

using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Net;
using System.Web;

namespace SomeNamespace {
public class NameObjectCollectionBaseConverter {
    public static Dictionary<string, string> Convert(NameValueCollection coll) {
        var keyValues = new Dictionary<string, string>();
        var keys = coll.Keys;
        foreach(var key in keys) {
            var strKey = key.ToString();
            var value = coll.Get(strKey).ToString();
            keyValues.Add(strKey, value);
        }

        return keyValues;
    }
        public static Dictionary<string, string> Convert(WebHeaderCollection coll) {
        var keyValues = new Dictionary<string, string>();
        var keys = coll.Keys;
        foreach(var key in keys) {
            var strKey = key.ToString();
            var value = coll.Get(strKey).ToString();
            keyValues.Add(strKey, value);
        }

        return keyValues;
    }
        public static Dictionary<string, string> Convert(HttpApplicationStateBase coll) {
        var keyValues = new Dictionary<string, string>();
        var keys = coll.Keys;
        foreach(var key in keys) {
            var strKey = key.ToString();
            var value = coll.Get(strKey).ToString();
            keyValues.Add(strKey, value);
        }

        return keyValues;
    }
        public static Dictionary<string, string> Convert(HttpApplicationStateWrapper coll) {
        var keyValues = new Dictionary<string, string>();
        var keys = coll.Keys;
        foreach(var key in keys) {
            var strKey = key.ToString();
            var value = coll.Get(strKey).ToString();
            keyValues.Add(strKey, value);
        }

        return keyValues;
    }
        public static Dictionary<string, string> Convert(HttpApplicationState coll) {
        var keyValues = new Dictionary<string, string>();
        var keys = coll.Keys;
        foreach(var key in keys) {
            var strKey = key.ToString();
            var value = coll.Get(strKey).ToString();
            keyValues.Add(strKey, value);
        }

        return keyValues;
    }
        public static Dictionary<string, string> Convert(HttpClientCertificate coll) {
        var keyValues = new Dictionary<string, string>();
        var keys = coll.Keys;
        foreach(var key in keys) {
            var strKey = key.ToString();
            var value = coll.Get(strKey).ToString();
            keyValues.Add(strKey, value);
        }

        return keyValues;
    }

}
}