【问题标题】:C# pass child object to a method to be filled with the common properties of base classC#将子对象传递给要填充基类的公共属性的方法
【发布时间】:2016-12-04 13:54:03
【问题描述】:

我有一个基实体类,它由两个类派生,分别名为 Student 和 Department。

public abstract class Entity
{
    [Key]
    public string Id { get; set; }
    [Required]
    public DateTime Created { get; set; }
    [Required]
    public string CreatedBy { get; set; }
    [Required]
    public DateTime Modified { get; set; }
    [Required]
    public string ModifiedBy { get; set; }       
}

 public class Department : Entity
{
    [Required]
    [Index]
    [StringLength(128)]
    public string Name { get; set; }

    public virtual ICollection<Student> Students { get; set; }
}

 public class Student : Entity
    {
        [Required]
        [Index]
        [StringLength(128)]
        public string Name { get; set; }
        public string Phone { get; set; }

        [Required]
        public string DepartmentId { get; set; }
        [ForeignKey("DepartmentId")]
        public virtual Department Department { get; set; }        
    }

现在我想实例化派生类,但不想重复常见的初始化代码。我使用了 ref out 等方式,但它出现了构建错误。

    public Student CreateStudent()
    {
        Student student = new Student
        {
            Name = nameTextBox.Text,
            Phone = phoneTextBox.Text,
            DepartmentId = departmentComboBox.SelectedValue.ToString()
        };
        SetCommonValues(ref student);
        return student;
    }

    public Department CreateDepartment()
    {
        Department department=new Department()
        {
            Name = nameTextBox.Text
        };
        SetCommonValues(ref department);
        return department;
    }

    public void SetCommonValues(ref Entity entity)
    {
        entity.Id = Guid.NewGuid().ToString();
        entity.Created = DateTime.Now;
        entity.Modified = DateTime.Now;
        entity.CreatedBy = Constants.UserName;
        entity.ModifiedBy = Constants.UserName;            
    }

任何建议都将受到高度赞赏。

【问题讨论】:

  • 抽象类中的构造函数来完成SetCommonValues的工作?
  • 您能否提供有关如何调用代码的更多详细信息以及有关错误的详细信息?

标签: c# inheritance reference polymorphism


【解决方案1】:

我可能在这里遗漏了一些东西。您是否有任何特殊原因不选择抽象类中的构造函数,如下所示?

public abstract class Entity
{
    public string Id { get; set; }
    public DateTime Created { get; set; }
    public string CreatedBy { get; set; }
    public DateTime Modified { get; set; }
    public string ModifiedBy { get; set; }

    public Entity()
    {
        this.Id = Guid.NewGuid().ToString();
        this.Created = DateTime.UtcNow;
        this.Modified = this.Created;
    }

    public Entity(string createdBy, string modifiedBy) : this()
    {
        this.CreatedBy = createdBy;
        this.ModifiedBy = modifiedBy;
    }
}

public class Department : Entity
{
    public string Name { get; set; }

    public virtual ICollection<Student> Students { get; set; }
}

public class Student : Entity
{
    public string Name { get; set; }
    public string Phone { get; set; }

    public string DepartmentId { get; set; }
    public virtual Department Department { get; set; }
}

【讨论】:

  • 这里将created by和modified by作为参数传递不是一个好主意。想想 1. web api 场景(模型由框架自动绑定)
  • 3.我不应该强制孩子传递参数
  • 更新了答案。当您将实体用作模型时,您一定会遇到此类问题。模型应该有一个空的构造函数,因为在 web api 中会首先调用,所以稍后会填充这些值。因此人们使用验证属性来验证模型。现在,对于 createdBy 和 modifiedBy 参数,我很确定它们没有被请求填充,甚至没有在请求模型中传递,因为它们应该在没有客户端参与的情况下填充。
  • 我使用了扩展方法。它更加解耦和更好的IMO。 :) 感谢您的贡献。请不要忘记查看我的仓库:github.com/foyzulkarim/GenericComponents
  • 扩展方法是带有语法糖的静态方法。为此,它很安静,但不要忘记您不能正确地对静态方法进行单元测试,除非它只做一些琐碎的事情,因为您将无法轻松地模拟它。你的目标是少写一行,现在仍然以扩展方法的形式存在。
【解决方案2】:

使用扩展方法架构解决

修改调用方法

 public Student CreateModel()
    {
        Student model = new Student
        {
            Name = nameTextBox.Text,
            Phone = phoneTextBox.Text,
            DepartmentId = departmentComboBox.SelectedValue.ToString(),                
        };
        model.SetCommonValues();
        return model;
    }

而SetCommonValues方法是

  public static Entity SetCommonValues(this Entity entity)
    {
        entity.Id = Guid.NewGuid().ToString();
        entity.Created = DateTime.Now;
        entity.Modified = DateTime.Now;
        entity.CreatedBy = Constants.UserName;
        entity.ModifiedBy = Constants.UserName;
        return entity;
    }

我可以将扩展方法标记为 void,但为了可扩展性,我返回了对象。

【讨论】:

    猜你喜欢
    • 2017-09-13
    • 1970-01-01
    • 1970-01-01
    • 2013-06-26
    • 2015-08-18
    • 2017-06-21
    • 2011-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多