假设我有一个Person
列表(这是一个类)。它包含大约20个字段(Name,Surname,Age,DateOfBirthdate等)。所以我得到了这个清单:
var listOfPersons= MyContext.Persons.Cast<Person>();
现在,我需要迭代这个List,并为每个Person
添加一个新字段(它不在课堂中),叫做CurrentDateTime
。
我可以使用新字段创建一个新对象,并将Person中的“复制和粘贴”值复制到新类。有些事情喜欢:
PersonNew newPerson = new PersonNew("Name", "Surname", "Age", "DateOfBirthdate", ... "CurrentDateTime");
但如果将来我更改Person类,这是非常糟糕的。那么,是否有一个“扩展人”的战略?这需要Person实例(无论它是什么)并添加新字段?
答案 0 :(得分:1)
您可以使用Automapper创建一些从PersonNew
创建Person
的静态方法。
public class PersonNew : Person
{
public static PersonNew CreateFromPerson(Person person, DateTime currentDateTime)
{
var newPerson = Mapper.Map<PersonNew>(person);
newPerson.CurrentDateTime = currentDateTime;
}
}
答案 1 :(得分:0)
我认为您描述的解决方案运行正常。如果你想在不扩展Person
类的情况下跟踪每个人的生日,你可以使用一个Dictionary对象
var listOfPersons = MyContext.Perons.Cast<Person>();
Dictionary<Person, DateTime> birthdays = new Dictionary<Person, DateTime>
foreach(Person person in listOfPersons)
{
birthdays.Add(person, getBirthday(person);
}
答案 2 :(得分:0)
一种解决方案是让您的课程partial
,并将您的字段添加到您班级的另一个partial
定义中:
public partial class Person
{
public string Name { get; set; }
public string FirstName { get; set; }
...
}
...
public partial class Person
{
public DateTime CurrentDateTime { get; set; }
}
...
var listOfPersons = MyContext.Persons.Cast<Person>();
foreach (var person in listOfPersons)
{
person.CurrentDateTime = ....
}
请注意,您将使用班级的相同的实例。
答案 3 :(得分:0)
首先,我建议使用扩展方法来预测集合而不是迭代。像那样:
var newCollection = oldCollection.Select(entity => MakeNewType(entity))
其次,通过新领域“扩展人”并不完全清楚你的意思。以下是您可以通过以下几种方式实现这一目标。
1)使用新字段创建另一个类并将其映射到旧字段。这是asp.net mvc应用程序的常见场景,您可以将模型映射到相应的视图模型。 Automapper对这些类型的场景非常有用(参见SławomirRosiekanwser)
2)利用c#4+中的dlr。 Yuo将失去动态对象的智能感知,但它们可以通过函数传递
var newPeople = people.Select(p =>
{
dynamic expando = new ExpandoObject();
expando.Id = p.Id;
expando.FirtName = p.FirtName;
/* ... */
expando.CurrentDateTime = DateTime.Now;
return expando;
});
3)使用匿名类型。匿名类型不能传递给另一个函数,因此当您需要在单个方法中快速投影数据并计算某些结果时,此方法很有用
var newPeople = people.Select(p => new
{
Id = p.Id,
FirtName = p.FirtName,
/* ... */
CurrentDateTime = DateTime.Now
});
在这两种情况下,您现在都可以访问新的“已创建”属性:
foreach(var p in newPeople)
{
Console.WriteLine("CurrentDateTime: {0}", p.CurrentDateTime);
}
4)如果你真的需要在运行时创建一个功能齐全的.net类,你可以使用Reflection.Emit。此方案通常用于创建动态代理 - 实现仅在运行时已知的某些功能的子类。实体框架就是这样做的。