将派生类属性转换为Base以生成泛型方法

本文关键字:泛型方法 Base 派生 属性 转换 | 更新日期: 2023-09-27 18:28:44

我有以下类:

public abstract class EntityBase
{
}
public class Employee:EntityBase
{
   public string Name {get;set}
   public string Address {get;set}  
}
public class Salary:EntityBase
{
   public int Basic {get;set}
   public int DA {get;set}  
}

我有另一个类/方法以基本类型返回实体数据:

public abstarct class EntityDataBase
{
   EntityBase GetEntityData();
}
public class EmployeeData:EntityDataBase
{
   EntityBase GetEntityData()
   {
      Employee emp=new Employee();
      return emp;
   }
 }  
public class SalaryData:EntityDataBase
{
   EntityBase GetEntityData()
   {
      Salary sal=new Salary();
      return sal;
   }
 }  

我有另一个显示实体类型的类。我想在类中编写一个通用方法来显示任何实体的数据。我已经实现了如下的类/方法:

public class DisplayEntities
{ 
  public EntityDataBase entityData {get;set}
  public EntityDataBase entity {get;set}
  public DisplayData()
  {
    entity =  entityData.GetEntityData(); 
    //Display Data using some display mechanism
  } 
 }

我使用的代码下面的代码从客户:

 Employee emp = new Employee();
 EmployeeData empData = new EmployeeData();
 DisplayEntities dispEntity= new DisplayEntities();
 dispEntity.entityData =  empData;
 dispEntity.entity= emp;
 dispEntity.DisplayData();

但该代码无法显示实体的数据。如何编写一个泛型方法来将任何实体类型传递给方法?

将派生类属性转换为Base以生成泛型方法

您可以使用反射获取对象的公共属性。这里有一个例子:

EntityBase entity = new Employee();
var properties = entity.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
foreach (var  property in properties)
{
    Console.WriteLine(string.Format("Name = {0}, Value = {1}",
        property.Name,
        property.GetValue(entity)));
}

问题是您没有通过显示实体数据来定义您所理解的内容。是否要显示对象的描述、属性列表和内存消耗?

如果您希望实体显示有关对象的一些基本信息,那么您可能应该在子类的级别(即从EntityBase继承的任何类的级别)实现这样做的机制。为了确保每个派生类都能实现此方法,您应该在父类中将DisplayData方法标记为abstract。比如说:

public abstract class EntityBase
{
    public abstract string DisplayData();
}

那么从EntityBase派生的任何类都必须实现DisplayData:

public class Employee : EntityBase
{
    public string Name { get; set; }
    public string Address { get; set; }
    public string DisplayData()
    {
        return string.Format("Name: {0}; Address: {1}", this.Name, this.Address);
    }
}

现在您可以使用该方法的结果。

至于您的DisplayEntities类,我认为以您的方式实现该类没有多大意义。看看会发生什么:1)您创建了一个新的Employee;2) 该员工被传递到CCD_ 8类;3) 在DisplayEntities类中,您调用GetEntityData来创建另一个新的Employee;4) 您用步骤3中创建的新员工覆盖步骤1中的员工;5) 显示员工数据。

但数据总是一样的——总是关于新创建的员工的信息。其次,在步骤1和3中创建Employee。但从第一步开始的那个家伙从未真正被使用过。在您的解决方案中,您只能访问在第三步中创建的员工。

也许值得重新考虑EntityBaseEntityDataBase的设计以及它们之间的关系?

话虽如此,如果你仍然希望你的类以通用的方式实现,下面是实现:

public class DisplayEntities<T, K>
    where T : EntityDataBase
    where K : EntityBase
{
    public T entityData { get; set; }
    public K entity { get; set; }
    public void DisplayData()
    {
        entity = (K)entityData.GetEntityData();
        Console.WriteLine(entity.DisplayData());
    }
}