获取参数,确定其是否为对象或列表<&gt ;;如果列表<>然后循环并将每个项目视为对象

时间:2013-08-15 21:03:28

标签: c# list generics casting

目标

获取一个对象或列表<>。

如果它是一个物体,那就用它做(做完)。

如果它是一个列表<> (任何类型的列表<>)然后循环遍历每个项目,并对每个项目执行类似的操作,返回字典或数组(此时返回类型不重要)。

到目前为止,对象位......

  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;
  }

接下来我需要确定它是一个对象还是一个列表&lt;&gt;,我已经尝试了各种各样的泛型,我遇到的最大问题是将它投入到列表&LT;&GT;未知类型。

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

2 个答案:

答案 0 :(得分: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;
}

但请注意,如果您实际尝试提供两个或更多项,则会失败,因为它会尝试将相同的键添加到字典中两次。如果您尝试传递没有指定属性之一的对象,它也将失败。在这些情况下,目前还不清楚你想要这个方法做什么,但这段代码似乎只是一个例子,所以你必须在实际代码中找出这个细节。

答案 1 :(得分:0)

FWIW,List<T>同时为IEnumerable<T>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()),类似于类型的方式检查完成。