如何扩展类的字段?
本文关键字:字段 扩展 何扩展 | 更新日期: 2023-09-27 18:02:40
假设我有一个Person
的列表(这是一个类)。它包含大约20个字段(Name、姓、Age、DateOfBirthdate等等)。所以我得到了这个列表:
var listOfPersons= MyContext.Persons.Cast<Person>();
现在,我需要遍历这个列表,并为每个Person
添加一个新字段(它不存在于类中),假设称为CurrentDateTime
。
我可以用新字段创建一个新对象,并写上"copy &将"Person"的值粘贴到新的"Class"中。小明:
PersonNew newPerson = new PersonNew("Name", "Surname", "Age", "DateOfBirthdate", ... "CurrentDateTime");
但是,如果将来我更改Person类,这将是非常糟糕的。那么,是否存在一种将Person"扩展"到新领域的策略呢?它接受Person实例(无论它是什么)并添加新字段?
您可以使用Automapper创建一些静态方法从Person
创建PersonNew
。
public class PersonNew : Person
{
public static PersonNew CreateFromPerson(Person person, DateTime currentDateTime)
{
var newPerson = Mapper.Map<PersonNew>(person);
newPerson.CurrentDateTime = currentDateTime;
}
}
我认为你描述的解决方案很好。如果您希望在不扩展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);
}
一个解决方案是使您的类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 = ....
}
请注意,您将使用与类相同的实例。
首先,我建议使用扩展方法来投影集合,而不是迭代。像这样:
var newCollection = oldCollection.Select(entity => MakeNewType(entity))
第二,你所说的用新字段"扩展Person"是什么意思并不完全清楚。这里有几个方法可以让你做到这一点。
1)用新字段创建另一个类,并将其映射到旧的字段。这是asp.net mvc应用程序的常见场景,您将模型映射到适当的视图模型。Automapper对于这些类型的场景很有用(参见Sławomir Rosiek answer)
2)利用c# 4+中的dlr。您将失去动态对象的智能感,但它们可以在函数
中传递。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。此场景通常用于创建动态代理——实现某些仅在运行时才知道的功能的子类。