将混凝土物体制成“;对象“;丢失属性

本文关键字:对象 属性 混凝土 | 更新日期: 2023-09-27 18:25:35

如果我有以下类

Person {
 string FirstName {get;set;}
 string LastName {get;set;}
}

在另一个课堂上,我做以下

OtherClass {
 List<Person> personList = new List<Person(/*10 people in here*/);
 List<Object> personObjectList = new List<Object>();
 foreach (Person p in personList) {
  personObjectList.Add(p);
 }
}

然后我试着做

personObjectList[0].FirstName;

为什么没有识别出该对象具有FirstName属性?我没有意识到改变对象的类型会使其失去属性。

感谢

将混凝土物体制成“;对象“;丢失属性

它不会丢失其属性;编译器就是不知道它们的存在。要获得属性,您需要将其强制转换回Person

name = ((Person)personObjectList[0]).FirstName;

var person = personObjectList[0] as Person;
if (person != null)
    name = person.FirstName;

如果强制转换失败,第一个样式将引发异常。如果强制转换失败,第二个样式将返回null,因此如果这样做,则应该检查null

您有两个主要选择。按照我的建议。。它们是:

按视图创建视图模型。这些是UI层中的对象,表示各个视图的特定数据。您可以将域模型映射到控制器中的视图模型。像AutoMapper和ValueInjecter这样的库可以帮助您删除这方面的许多管道代码。请注意不要将业务逻辑引入映射

这有两个主要好处:

  • 视图可以使用强类型视图模型,而不是到处强制转换
  • 您的视图模型和域模型可以独立发展

第二点非常重要。当你允许你的视图直接使用域模型时,你会陷入很多大陷阱。最大的问题是,您将开始在任何地方使用Html.HiddenFor<input type="hidden"/>来在页面之间持久化数据,这很快就会成为您要处理的噩梦。

此外,具有单独的视图模型允许模型独立地发展。您的域模型可能具有与业务需求相关的属性,但视图模型可能包含纯粹与UI问题相关的属性。比如UI级验证、聚合属性(比如视图模型中的FullName而不是FirstName+Surname)。灵活性真的很好。

其次,针对我上面所说的一切,您可以在视图的顶部放置一个@using指令,以包括对象所在的命名空间。这允许您使用视图中的模型。

我强烈建议你调查一下我提供给你的第一个选项。以后在你的项目中你会感觉更好。