【问题标题】:Cast Object to Generic List将对象转换为通用列表
【发布时间】:2011-02-19 16:37:09
【问题描述】:

我有 3 个泛型类型列表。

List<Contact> = new List<Contact>();
List<Address> = new List<Address>();
List<Document> = new List<Document>();

并将其保存在类型为 object 的变量中。现在我需要做 Cast Back to List 来执行 foreach,有些是这样的:

List<Contact> = (List<Contact>)obj;

但 obj 内容每次都在变化,我有一些这样的:

List<???> = (List<???>)obj;

我有另一个变量保存当前的 obj 类型:

Type t = typeof(obj);

我可以这样做吗??:

List<t> = (List<t>)obj;

Obs:我没有列表中的当前类型,但我需要转换,我现在不需要另一种形式:

List<Contact> = new List<Contact>();

【问题讨论】:

    标签: c# generics list


    【解决方案1】:

    我在 SL 5 上进行了多次试验和错误,但它也应该适用于常规 C#。您还需要将 LINQ 添加到您的使用列表中,以便后半部分工作。

        List<object> myAnythingList = (value as IEnumerable<object>).Cast<object>().ToList()
    

    享受吧!

    【讨论】:

    • 这是我在过去一小时内通过 Stack Overflow 找到的唯一可行的解​​决方案。谢谢!我的问题是,在反射中,.Invoke() 返回和对象,在运行时是 List。但是我不知道类,只知道接口IUnifyingDef。直接转换和使用 Convert() 都会引发异常或无法编译。
    • 这种方法的问题是ToList() 创建了另一个列表,它不是原始实例
    • 我自己永远不会找到这个。非常感谢。
    【解决方案2】:

    真是个棘手的问题。试试这个:

    List<Contact> c = null;
    List<Address> a = null;
    List<Document> d = null;
    
    object o = GetObject();
    
    c = o as List<Contact>;
    a = o as List<Address>;
    d = o as List<Document>;
    

    在 c、a 和 d 之间,有 2 个空值和 1 个非空值,即 3 个空值。


    采取 2:

    object o = GetObject();
    IEnumerable e = o as IEnumerable;
    IEnumerable<Contact> c = e.OfType<Contact>();
    IEnumerable<Address> a = e.OfType<Address>();
    IEnumerable<Document> d = e.OfType<Document>();
    

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题,并通过查看铸造对象的目的来解决它。您真的需要将其转换为特定的(封闭的)泛型类型吗?在我的例子中,(开放的)泛型类型有一个我用来转换它的接口。

      var list = obj as IUsefulInterface;
      
      list.MethodThatIAmInterestedIn();
      

      【讨论】:

        【解决方案4】:

        这样的通用解决方案(使用基于System.Type 对象的泛型参数实例化类型)是不可能的。但是,如果您真的只处理这三种类型,那么您很幸运,因为这很容易:

        Type t = typeof(obj);
        
        if (t == typeof(List<Contact>)) {
            var contactList = (List<Contact>)obj;
            // do stuff with contactList
        
        } else if (t == typeof(List<Address>)) {
            var addressList = (List<Address>)obj;
            // do stuff with addressList
        
        } else if (t == typeof(List<Document>)) {
            var documentList = (List<Document>)obj;
            // do stuff with documentList
        }
        

        【讨论】:

          【解决方案5】:

          我在编写验证属性时遇到了这个问题,我从ValidationContext 收到了一个对象,并且知道它需要是一个列表,但不是列表的内容。当我尝试将其转换为 IEnumerable&lt;object&gt; 时,它引发了异常,但它可以转换为 IEnumerable,然后通过 linq 允许 .Cast&lt;object&gt;()

          最终起作用的是:

          var enumerable = listObject as IEnumerable;
          var list = enumerable.Cast<object>().ToList();
          

          【讨论】:

            【解决方案6】:

            不,你不能在不绕过角落的情况下进行转换(这就是:反射),泛型类型参数必须在编译时知道。你当然可以这样做:

            content.Where(o =&gt; o is type).ToList().Foreach(stuff);

            【讨论】:

              【解决方案7】:

              我遇到了同样的问题 - 我有一个数据类型仅在运行时已知的集合,我无法将其转换为任何内容。上述解决方案均无效。最后我通过序列化为 JSON 并反序列化来解决它。当然这并不理想,但可能会对某人有所帮助。

              string jsonString = JsonConvert.SerializeObject(myObject);
              jsonString = "{ values:" + jsonString + "}";
              
              JObject j = JObject.Parse(jsonString);
              
              //now we can iterate over the list
              foreach (var x in j["values"])
              {
                  string name = x.ToString();
                  ...
              }
              

              【讨论】:

                【解决方案8】:

                您可能需要这样做:

                if(object is List)
                {
                    list = (List)object
                }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-12-02
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-10-01
                  相关资源
                  最近更新 更多