使具体对象键入“对象”会丢失属性

时间:2014-10-06 03:29:58

标签: c#

如果我有以下课程

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属性?我没有意识到改变对象的类型会使它失去属性。

谢谢

2 个答案:

答案 0 :(得分:3)

它不会失去它的属性;编译器只是不知道它们存在。要获取属性,需要将其强制转换为Person

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

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

如果转换失败,第一个样式将抛出异常。如果演员表失败,第二个样式将返回null,因此如果你这样做,你应该检查null

答案 1 :(得分:2)

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

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

这有两个主要好处:

  • 您的视图可以使用强类型视图模型,而不是随处投射
  • 您的视图模型和域模型可以独立发展

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

此外,使用单独的视图模型可以使模型独立发展。您的域模型可能具有与业务需求相关的属性 - 但您的视图模型可以包含纯粹与UI关注相关的属性。诸如UI级别验证,聚合属性(例如视图模型中的FullName而不是FirstName + Surname)之类的事情。拥有的灵活性非常好。

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

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