【问题标题】:Cannot cast IEnumerable<ViewmodelA> to IEnumerable<ViewmodelB>无法将 IEnumerable<Viewmodel> 转换为 Enumerable<Viewmodel>
【发布时间】:2019-11-19 07:02:13
【问题描述】:

我检索到IEnumerable&lt;ViewmodelA&gt; 类型的列表,需要将此列表转换为IEnumerable&lt;ViewmodelB&gt;。每个viewmodel 都有相同和不同的属性,我只想映射相同的属性(姓名和姓氏)。是否可以使用拳击或AutoMapper?我试过拳击,但它不起作用:(

IEnumerable<ViewmodelB> newList;
newList = (IEnumerable<ViewmodelB>)demoService.GetList(); //returns IEnumerable<ViewmodelA>

ViewodelA:

public class ViewmodelA {

    public string Name { get; set; }

    public string Surname { get; set; }

    public string School { get; set; }

    public string Number { get; set; }
}

ViewodelB:

public class ViewmodelB {

    public string Name { get; set; }

    public string Surname { get; set; }

    public string Work { get; set; }

    public string Address { get; set; }
}

【问题讨论】:

  • 您不能“投射”不同或不兼容类型的东西。您可以“转换”它们,但前提是存在合理的转换。为什么你认为你可以转换这些对象?
  • “我试过拳击”????您能否解释一下与帖子中显示的代码相关的含义? (没有显示struct - 那么您希望拳击到底发生在哪里?)
  • @Enigmativity 因为有一个服务正在检索IEnumerable&lt;ViewmodelA&gt; 中的列表,我想使用这种方法。另一方面,我有一些额外的属性,不想修改 ViewmodelA,因为它是通用视图模型。
  • @AlexeiLevenkov (IEnumerable&lt;ViewmodelB&gt;)demoService.GetList()
  • @hexadecimal 抱歉,那一行是什么意思?这是对我关于“拳击”问题的某种回答吗?

标签: c# asp.net asp.net-mvc asp.net-core viewmodel


【解决方案1】:

您将无法将 ViewmodelA 转换为 ViewmodelB

我想到的前几个选项是:

  • 让两个类都继承自同一个基类,
  • 让两个类都实现一个接口,
  • 创建AB之间的转换机制。

【讨论】:

  • “创建A和B之间的转换机制。”.但是怎么做?请问有什么例子吗?
  • 请回复?
【解决方案2】:

对于像这个操作这样微不足道的事情,我想我会:

var modelbs = modelas.Select(
  a => new Viewmodelb(){
    Name = a.Name,
    Surname = a.Surname
  }
);

您可以让两个视图模型都从包含 Name 和 Surname 的基类继承,但请注意,这不允许您将 modela 转换为 modelb,您只能将 modela 转换为基类。

或者您可以在 modelb 中提供一个构造函数,该构造函数接受一个 modela 对象并从中提取姓名/姓氏,然后像这样使用它:

var modelbs = modelas.Select(
  a => new Viewmodelb(a)
);

您的 ViewmodelB 类看起来像:

public class ViewmodelB {

    public string Name { get; set; }

    public string Surname { get; set; }

    public string Work { get; set; }

    public string Address { get; set; }

    public ViewmodelB(ViewmodelA x){
      Name = x.Name;
      Surname = x.Surname;

      //maybe initialize other properties here
    }
}

【讨论】:

  • 是的,我正在寻找类似的东西。但我不知道它是否适用于 IEnumerable&lt;modela&gt; ?有什么想法吗?
  • 它适用于任何你喜欢的东西;您只是要求 LINQ 在一堆模型 a 对象上运行一个循环,并将一个新的模型 b 填充到一个集合中,其中 name 和 surname 道具已与模型 a 值结合在一起。这不是铸造或拳击
  • 对于我的情况在modelb 中提供一个构造函数,它接受一个modelb 对象并从中提取姓名/姓氏 似乎更好。我怎样才能做到这一点?您能否通过使用 ViewmodelA 和 ViewmodelB 更新答案,包括这个?谢谢...
【解决方案3】:

你只能这样做:

IEnumerable<ViewmodelB> newList = demoService.GetList().Select(a => SomeMethodCreatingBFromA(a));

SomeMethodCreatingBFromA 可以是任何东西——调用构造函数、AutoMapper 等等。 AutoMapper 用的不多,但我想它有一个在集合之间转换的方法。

【讨论】:

  • 似乎是个好方法。 SomeMethodCreatingBFromA 的任何示例?请问可以发帖吗?
  • ViewModelB SomeMethodCreatingBFromA(ViewModelA a) { return new ViewModelB() { Name = a.Name, Surname = a.Surname, ... }; }
【解决方案4】:

如果您只想使用公共属性,请创建一个基类或接口,在其中定义公共属性并从中派生两个类。然后就可以使用基类或者接口了。

【讨论】:

    【解决方案5】:

    以下是@tymtam answer 的示例

    1. 让两个类都继承自同一个基类

    2. 让两个类都实现一个接口

    3. 创建A和B之间的转换机制

    {

    /// <summary>
    /// Using the same base class
    /// </summary>
    public class BaseClass
    {
        public string Property { get; set; }
    }
    
    public class ViewModelA : BaseClass
    {
        public string Property { get; set; }
    }
    public class ViewModelB : BaseClass
    {
        public string Property { get; set; }
    }
    
    
    /// <summary>
    /// Using the same interface
    /// </summary>
    public interface BaseInterface
    {
        string Property { get; set; }
    }
    
    public class ViewModelA : BaseInterface
    {
        public string Property { get; set; }
    }
    public class ViewModelB : BaseInterface
    {
        public string Property { get; set; }
    }
    
    
    /// <summary>
    /// Create a conversion mechanism. This can be done in either in ViewModelA or ViewModelB
    /// </summary>
    
    public class ViewModelA
    {
        public string Property { get; set; }
    
        public static implicit operator ViewModelA(ViewModelB model) => new ViewModelA { Property = model.Property };
        public static implicit operator ViewModelB(ViewModelA model) => new ViewModelB { Property = model.Property };
    }
    public class ViewModelB
    {
        public string Property { get; set; }
    }
    

    【讨论】:

    • 谢谢,但我无法编辑 ViewmodelA 并修改其继承。
    • 然后使用第三种方法,implicit operator
    • 非常感谢您的帮助。我按照 Caius Jard 的建议使用了以前的方法。谢谢并投票;)
    猜你喜欢
    • 1970-01-01
    • 2021-03-06
    • 2020-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-24
    • 1970-01-01
    • 2012-08-06
    相关资源
    最近更新 更多