C#中的inheritance:创建一个用超类实例的值初始化的实例
我很确定这是不可能的,但是这里……
我在C#中有一个名为Person的自定义类,它有一些属性,如Age,Height等。
然后我创建一个名为Employee的新类,它inheritance自Person但我还没有向Employee添加任何其他属性。 所以它基本上只是一个人,除了它被称为员工。
现在说我有一个名为SomePerson的Person实例。 如何创建一个新的Employee实例,该实例具有从Personinheritance的所有值,设置为SomePerson中的值。 就像从Person转换为Employee一样..但是我不必手动指定需要设置的每个属性..
就像是..
Employee NewEmployee = (Employee)SomePerson;
但是当然你得到的错误是“无法将一个人转变为员工”等。
如果你说在涉及的对象中有300个属性,AutoMapper是唯一可行的解决方案吗?
更新:
Auto-Mapper似乎无法处理我的对象..
Employee SomeEmployee = EmployeeRepository.GetEmployee(SomeEmployeeID); // Populate the ViewModel with the Person fetched from the db, ready for editing.. VMEmployee EmployeeToEdit = Mapper.Map(SomeEmployee); // ViewModel based on Employee with Validation applied.. [MetadataType(typeof(Employee_Validation))] public class VMEmployee : Employee { // Absolutely nothing here }
其中“Employee”由LINQ to SQL自动生成。
在这种情况下,AutoMapper是一个很好的解决方案。 如果您不打算使用属性映射框架,并且您不愿意创建复制构造函数public Employee(Person person)
或隐式/显式转换,那么您希望如何复制属性。 实际上你可以
1.Reflection
public void Map(TSource source, TDestination destination) { var props = typeof(TSource).GetProperties(BindingFlags.Public | BindingFlags.Instance); var type = typeof(TDestination); foreach (var prop in props) { object value = prop.GetValue(source, null); var prop2 = type.GetProperty(prop.Name); if (prop2 == null) continue; if (prop.PropertyType != prop2.PropertyType) continue; prop2.SetValue(destination, value, null); } }
2.Copy构造函数
public Employee(Person person) { // Copy properties }
3.隐含/显式转换
public static implicit operator Employee(Person person) { // Build instance and return }
4.AutoMapper
Mapper.Map(person);
5.组合3/4:
public static implicit operator Employee(Person person) { return Mapper.Map(person); }
关于隐式/显式转换运算符的注释:我相信使用它们不会生成符合CLS的代码。
正如@Mitch Wheat已经说过的,如果你有一个拥有超过300个属性的对象,我会重新考虑该对象实际代表什么。 重构重构重构。
您可以使用automaper来实现此目的,无需任何配置。
这是一个例子:
Employee employee = Mapper.Map(person);
在Employee
上创建一个带有Person
实例的构造函数。 当然你必须填写所有的属性(也许Resharper可以帮忙吗?)
如果您具有相对简单的属性,则reflection可能是映射属性值的最快且最简单的解决方案。
与流行的看法相反,反思确实不是那么糟糕; Rick Strahl在这篇文章中消除了这个神话: http : //www.west-wind.com/weblog/posts/351.aspx 。
为Employee
创建以下构造函数:
public Employee(Person person) { // clone property values foreach (var property in person.GetType().GetProperties().Where(property => property.CanRead && property.CanWrite)) { property.SetValue(this, property.GetValue(user, null), null); } }
现在简单地实例化一个Employee
对象,如下所示:
Employee NewEmployee = new Employee(SomePerson);
“它们是复杂的LINQ to SQL模型类” – Aaron
如果您有一个映射到几个可能类之一的表,则可以使用LINQ to SQL的inheritance层次结构 。 这意味着如果对多种类型的概念实体使用相同的表,则可以让LINQ to SQL自动创建相应的类。 每个类可以具有不同的属性,这些属性可以是表中列的子集。
有一些限制。 每个inheritance层次结构只能使用一个表,并且必须有一个鉴别器列,告诉LINQ to SQL应该使用哪个类。
当你开始一份新工作时,出生的新人是不是你,而你的老人是谁?
如果您的设计基于该场景,那么您的组织中的实践就非常奇怪。
相反,一个人与雇主有雇佣关系。
不要使用inheritance来建模角色; 允许同一个人拥有代表他们与其他对象的关系的角色。