0

目标

取一个对象或列表<>。

如果它是一个对象,那么用它做一些事情(完成)。

如果它是一个列表<>(任何类型的列表<>),则遍历每个项目,并对每个项目做类似的事情,返回一个字典或数组(目前返回类型并不重要)。

我到目前为止所拥有的,对象位...

  public static Dictionary<string, object> Pick (object obj, Array Picklist) {
    Dictionary<string, object> dic = new Dictionary<string, object> ();
    foreach (string key in Picklist) {
      dic.Add(key, obj.GetType ().GetProperty (key).GetValue (obj, null));
    }
    return dic;
  }

所以接下来我需要确定它是一个对象还是一个列表<>,我尝试了各种泛型,我遇到的最大问题是将它转换为一个未知类型的列表<>。

任何这样做或理解正确步骤的方式,将不胜感激。

4

2 回答 2

3

你可以这样做:

public static Dictionary<string, object> Pick(object obj, Array Picklist) 
{
    Dictionary<string, object> dic = new Dictionary<string, object> ();
    IEnumerable items = obj as IEnumerable ?? new[] { obj };
    foreach(string key in Picklist) 
    {
        foreach(object item in items)
        {
            dic.Add(key, item.GetType().GetProperty(key).GetValue(item, null));
        }
    }

    return dic;
}

但是请注意,如果您实际上尝试提供两个或更多项目,这将失败,因为它会尝试将相同的键添加到字典中两次。如果您尝试传递不具有指定属性之一的对象,它也会失败。目前尚不清楚在这些情况下您希望此方法做什么,但此代码似乎只是一个示例,因此您必须在实际代码中弄清楚该细节。

于 2013-08-15T21:07:16.307 回答
0

FWIW, List<T>is both IEnumerable<T>and IEnumerable(意味着它的内容可以列举为 的实例object)。您可以使用IEnumerable这样的链接:

object o = new List<string>() ;
...
((IEnumerable)o).Cast<object>().DoSomethingLinqy( x => ... ) ;

如果您只对区分List<T>(而不是它的子类型)和任何其他类(包括 的子类型)感兴趣List<T>,那么这段代码应该可以:

object o = GetSomeObject() ;
bool isGenericList = o.GetType().GetGenericTypeDefinition() == typeof(List<>) ;

如果您需要将List<T>其视为相同的子类型,那么您需要列出以下内容:

static bool IsInstanceOfGenericType( object o, Type genericType )
{
    bool isGenericTypeInstance = false ;
    for ( Type t = o.GetType() ; t != null && !isGenericTypeInstance ; t = t.BaseType )
    {
      isGenericTypeInstance =  t.IsGenericType
                            && t.GetGenericTypeDefinition() == genericType
                            ;
    }
    return isGenericType ;
}

你会这样使用它:

object o = GetSomeObject() ;
bool isGenericList = isInstanceOfGenericType( o , typeof(List<>) ) ;

如果您需要能够将对象识别为实现通用接口,那么复杂度就会上升。上面的函数需要修改,以便在运行继承层次时,它不仅检查类型,而且检查类型实现的每个接口(使用Type.GetInterfaces())以类似于类型检查的方式进行。

于 2013-08-15T21:54:09.037 回答