0

假设我有一个列表Person(这是一个类)。它包含大约 20 个字段(姓名、姓氏、年龄、出生日期等)。所以我得到了这个清单:

var listOfPersons= MyContext.Persons.Cast<Person>();

现在,我需要遍历这个列表,并为每个Person添加一个新字段(它在类中不存在),比如说,CurrentDateTime.

我可以使用新字段创建一个新对象,并将值从 Person 复制并粘贴到新类。像:

PersonNew newPerson = new PersonNew("Name", "Surname", "Age", "DateOfBirthdate", ... "CurrentDateTime");

但是,如果将来我更改 Person 类,这将非常糟糕。那么,有没有一种策略可以用一个新的领域来“扩展人”呢?这需要 Person 实例(无论它是什么)并添加新字段?

4

4 回答 4

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;
    }
}
于 2013-03-06T16:15:46.610 回答
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); 
}
于 2013-03-06T16:16:19.893 回答
0

一种解决方案是创建您的 class partial,并将您的字段添加到您的 class 的另一个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 = ....
}

请注意,您将使用类的相同实例。

于 2013-03-06T16:16:31.277 回答
0

首先,我建议使用扩展方法来投影集合而不是迭代。像那样:

var newCollection = oldCollection.Select(entity => MakeNewType(entity))

其次,使用新字段“扩展人”是什么意思并不完全清楚。以下是您可以实现这一目标的几种方法。

1)使用新字段创建另一个类并将其映射到旧类。这是 asp.net mvc 应用程序的常见场景,您将模型映射到适当的视图模型。Automapper 对于这些类型的场景很有用(参见 Sławomir Rosiek anwser)

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。这种情况通常用于创建动态代理 - 实现某些仅在运行时才知道的功能的子类。实体框架执行此操作。

于 2013-03-06T17:41:44.333 回答