可以从派生自 NameObjectCollectionBase 的不同对象中提取值的单一方法?
Single method that can pull values from different objects that derive from NameObjectCollectionBase?
我正在处理几个源自 NameObjectCollectionBase
的集合。有没有一种方法可以用一种方法从 类 中提取 key/value 对,这些对从 NameObjectCollectionBase
派生?
我可以获取集合中的键,但无法获取值。到目前为止,我已经尝试过接受 NameObjectCollectionBase
和 IEnumerable<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;
}
}
}
我正在处理几个源自 NameObjectCollectionBase
的集合。有没有一种方法可以用一种方法从 类 中提取 key/value 对,这些对从 NameObjectCollectionBase
派生?
我可以获取集合中的键,但无法获取值。到目前为止,我已经尝试过接受 NameObjectCollectionBase
和 IEnumerable<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;
}
}
}