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

Single method that can pull values from different objects that derive from NameObjectCollectionBase?

我正在处理几个源自 NameObjectCollectionBase 的集合。有没有一种方法可以用一种方法从 类 中提取 key/value 对,这些对从 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 有从基础集合中检索项目的方法,但这些方法对于我接收到方法中的对象是受保护的。

编辑:提取方法不必通过括号。我真的只是在寻找通用的方法。

NameObjectCollectionBase 没有为括号提供重载(据我在文档中所见)。据我所知,这是为了让您在需要时提供括号的实现。

看看这个例子:

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

MSDN

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

此外,您不能通过括号访问 IEnumerable<T>。您只能使用 ElementAt(int).

获取元素

好吧,经过多次试验,我最终选择了 T4 模板。虽然,无可否认,在这之后我不得不同意任何人的说法,如果有一种方法来处理每个不同的容器会更容易。

无论如何。基本上,此模板提取 NameObjectCollectionBase 的所有 public 子项,这些子项具有 Get(string) 方法签名和字符串或对象 return 类型,然后为每个匹配 class 剔除一个 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;
    }

}
}