如何以编程方式确定Key值对中的对象是否可枚举?
我需要知道值字段中的对象是List还是Array.我应该能够确定对象是什么类型的可枚举类型(例如字符串列表或一组int)
List<KeyValuePair<string, object>> lKVP = new List<KeyValuePair<string, object>>();
List<string> lS = new List<string> { "s1", "s2" };
lKVP.Add(new KeyValuePair<string, object>("PassPhrase", "E92D8719-38A6-0000-961F-0E66FCB0A363"));
lKVP.Add(new KeyValuePair<string, object>("Test", lS));
Run Code Online (Sandbox Code Playgroud)
我尝试过的:
1)
foreach(KeyValuePair<string,object> kvp in _ParameterReplacement)
{
if(kvp.Value is Enumerable)
{
Console.WriteLine("Yes");
}
else
{
Console.WriteLine("No");
}
}
Run Code Online (Sandbox Code Playgroud)
2)
foreach(KeyValuePair<string,object> kvp in _ParameterReplacement)
{
if(kvp.Value.GetType() == typeof(IEnumerable<object>))
{
Console.WriteLine("Yes");
}
else
{
Console.WriteLine("No");
}
}
Run Code Online (Sandbox Code Playgroud)
使用dynamic
您可以利用dynamic关键字来执行此操作,但我认为这对您来说可能太慢了。
然而,这就是你可以做到的。这将调用and的强类型enumerate()方法,或者如果值既不是列表也不是数组,它将调用仅接受一个对象的重载。List<T>T[]enumerate()
我不完全确定这就是您想要的,但它确实为您的 KVP 列表中的列表和数组提供了强类型枚举。
请注意,根据您的规范,这仅考虑列表和数组类型;其他可枚举类型(如字符串、HashSet等)不予考虑:
using System;
using System.Collections.Generic;
namespace ConsoleApp1
{
sealed class Program
{
void test()
{
List<KeyValuePair<string, object>> lKVP = new List<KeyValuePair<string, object>>();
List<string> lS = new List<string> { "s1", "s2" };
string[] aS = {"a1", "a2"};
lKVP.Add(new KeyValuePair<string, object>("String", "E92D8719-38A6-0000-961F-0E66FCB0A363"));
lKVP.Add(new KeyValuePair<string, object>("Test", lS));
lKVP.Add(new KeyValuePair<string, object>("IntNotEnumerable", 12345));
lKVP.Add(new KeyValuePair<string, object>("Array", aS));
foreach (KeyValuePair<string,object> kvp in lKVP)
{
enumerate((dynamic) kvp.Value);
}
}
static void enumerate<T>(List<T> list)
{
Console.WriteLine("Enumerating list of " + typeof(T).FullName);
foreach (var item in list)
Console.WriteLine(item);
Console.WriteLine();
}
static void enumerate<T>(T[] array)
{
Console.WriteLine("Enumerating array of " + typeof(T).FullName);
foreach (var item in array)
Console.WriteLine(item);
Console.WriteLine();
}
static void enumerate(object obj)
{
Console.WriteLine("Not enumerating type " + obj.GetType().FullName + " with value " + obj);
Console.WriteLine();
}
static void Main(string[] args)
{
new Program().test();
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用显式反射
这是一种使用反射来避免使用的方法dynamic,这意味着它要快得多 - 但正如您所看到的,它明显更加繁琐!
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
namespace ConsoleApp1
{
sealed class Program
{
void test()
{
List<KeyValuePair<string, object>> lKVP = new List<KeyValuePair<string, object>>();
List<string> lS = new List<string> { "s1", "s2" };
string[] aS = {"a1", "a2"};
lKVP.Add(new KeyValuePair<string, object>("String", "E92D8719-38A6-0000-961F-0E66FCB0A363"));
lKVP.Add(new KeyValuePair<string, object>("Test", lS));
lKVP.Add(new KeyValuePair<string, object>("IntNotEnumerable", 12345));
lKVP.Add(new KeyValuePair<string, object>("Array", aS));
var listEnumerator = this.GetType().GetMethod("enumerateList", BindingFlags.NonPublic | BindingFlags.Static);
var arrayEnumerator = this.GetType().GetMethod("enumerateArray", BindingFlags.NonPublic | BindingFlags.Static);
foreach (KeyValuePair<string, object> kvp in lKVP)
{
MethodInfo genericEnumerator = null;
var arrayElemType = arrayElementType(kvp.Value);
if (arrayElemType != null)
{
genericEnumerator = arrayEnumerator.MakeGenericMethod(arrayElemType);
}
else
{
var listElemType = listElementType(kvp.Value);
if (listElemType != null)
genericEnumerator = listEnumerator.MakeGenericMethod(listElemType);
}
if (genericEnumerator != null)
genericEnumerator.Invoke(null, new[] { kvp.Value });
else
Console.WriteLine("Not enumerating type: " + kvp.Value.GetType().FullName + "\n");
}
}
static Type arrayElementType(object sequence)
{
if (sequence is IEnumerable)
{
var type = sequence.GetType();
if (type.IsArray)
return type.GetElementType();
}
return null;
}
static Type listElementType(object sequence)
{
if (sequence is IEnumerable)
{
var type = sequence.GetType();
if (typeof(IList).IsAssignableFrom(type) && type.IsGenericType)
return type.GetProperty("Item").PropertyType;
}
return null;
}
static void enumerateList<T>(List<T> list)
{
Console.WriteLine("Enumerating list of " + typeof(T).FullName);
foreach (var item in list)
Console.WriteLine(item);
Console.WriteLine();
}
static void enumerateArray<T>(T[] array)
{
Console.WriteLine("Enumerating array of " + typeof(T).FullName);
foreach (var item in array)
Console.WriteLine(item);
Console.WriteLine();
}
static void Main(string[] args)
{
new Program().test();
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7879 次 |
| 最近记录: |