【问题标题】:Cast/Convert IEnumerable<T> to IEnumerable<U>?将 IEnumerable<T> 转换/转换为 IEnumerable<U>?
【发布时间】:2009-11-21 16:45:16
【问题描述】:

以下内容符合但在运行时抛出异常。我要做的是将一个 PersonWithAge 类转换为 Person 类。我该怎么做?解决方法是什么?

class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

class PersonWithAge
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        IEnumerable<PersonWithAge> pwa = new List<PersonWithAge>
        {
            new PersonWithAge {Id = 1, Name = "name1", Age = 23},
            new PersonWithAge {Id = 2, Name = "name2", Age = 32}
        };

        IEnumerable<Person> p = pwa.Cast<Person>();

        foreach (var i in p)
        {
            Console.WriteLine(i.Name);
        }
    }
}

编辑:顺便说一下,PersonWithAge 将始终包含与 Person 相同的属性以及更多属性。

编辑 2 对不起,伙计们,但我应该更清楚一点,比如我在一个包含相同列的数据库中有两个 db 视图,但视图 2 包含 1 个额外字段。我的模型视图实体是由模仿数据库视图的工具生成的。我有一个从类实体之一继承的 MVC 部分视图,但我有不止一种方法来获取数据...

不确定这是否有帮助,但这意味着我不能让 personWithAge 从 person 继承。

【问题讨论】:

    标签: c# ienumerable casting


    【解决方案1】:

    您不能投射,因为它们是不同的类型。你有两个选择:

    1) 更改类,使 PersonWithAge 继承自 person。

    class PersonWithAge : Person
    {
            public int Age { get; set; }
    }
    

    2) 创建新对象:

    IEnumerable<Person> p = pwa.Select(p => new Person { Id = p.Id, Name = p.Name });
    

    【讨论】:

      【解决方案2】:

      使用Select 而不是Cast 以指示如何执行从一种类型到另一种类型的转换:

      IEnumerable<Person> p = pwa.Select(x => new Person { Id = x.Id, Name = x.Name });
      

      同样PersonWithAge 将始终包含与Person 相同的属性,再加上更多,最好让它从Person 继承。

      【讨论】:

        【解决方案3】:

        您不能只是将两个不相关的类型相互转换。您可以通过让 PersonWithAge 从 Person 继承来将 PersonWithAge 转换为 Person。由于 PersonWithAge 显然是 Person 的一个特例,这很有意义:

        class Person
        {
                public int Id { get; set; }
                public string Name { get; set; }
        }
        
        class PersonWithAge : Person
        {
                // Id and Name are inherited from Person
        
                public int Age { get; set; }
        }
        

        现在,如果您有一个名为 personsWithAgeIEnumerable&lt;PersonWithAge&gt;,那么 personsWithAge.Cast&lt;Person&gt;() 将起作用。

        在 VS 2010 中,您甚至可以完全跳过演员表并执行 (IEnumerable&lt;Person&gt;)personsWithAge,因为 IEnumerable&lt;T&gt; 在 .NET 4 中是协变的。

        【讨论】:

          【解决方案4】:

          使 PersonWithAge 继承自 Person。

          像这样:

          class PersonWithAge : Person
          {
                  public int Age { get; set; }
          }
          

          【讨论】:

            【解决方案5】:

            您可能希望将代码修改为:

            class Person
            {
                    public int Id { get; set; }
                    public string Name { get; set; }
            }
            
            class PersonWithAge : Person
            {
                    public int Age { get; set; }
            }
            

            【讨论】:

              【解决方案6】:

              您可以保留IEnumerable&lt;PersonWithAge&gt;,但不要将其转换为IEnumerable&lt;Person&gt;。只需添加一个隐式转换即可在需要时将PersonWithAge 的对象转换为Person

              class Person
              {
                  public int Id { get; set; }
                  public string Name { get; set; }
                  public static implicit operator Person(PersonWithAge p)
                  {
                      return new Person() { Id = p.Id, Name = p.Name };
                  }
              }
              

              List<PersonWithAge> pwa = new List<PersonWithAge>
              Person p = pwa[0];
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-02-06
                • 2012-02-24
                • 2018-08-04
                • 2021-12-02
                • 1970-01-01
                相关资源
                最近更新 更多