【问题标题】:Create a Defensive Copy in the Constructor在构造函数中创建防御副本
【发布时间】:2016-02-18 01:01:39
【问题描述】:

以下只是示例代码,用于解释我无法理解的问题:

假设我有以下教授类,请注意公共 getter 和 setter:

    public class Professor
    {
        public string id {get; set; }
        public string firstName{get; set;}
        public string lastName {get; set;}

        public Professor(string ID, string firstName, string lastname)
        {
            this.id = ID;
            this.firstName = firstName;
            this.lastName = lastname;
        }


    }

课程:

public class Course
{
    string courseCode {get; private set;}
    string courseTitle {get; private set;}
    Professor teacher {get; private set;}

    public Course(string courseCode, string courseTitle, Professor teacher)
    {
        this.courseCode = courseCode;
        this.courseTitle = courseTitle;

    }
}

如何在 Course 类中制作 Professor 对象的防御性副本? here 提供的示例对日期对象是这样处理的。

fDateOfDiscovery = new Date(aDateOfDiscovery.getTime());

可以对 Course 类中的教授对象做同样的事情吗?

更新:

接受提供的答案是我想出的,对吗?

public class Professor
{
 public string id {get; set; }
 public string firstName{get; set;}
 public string lastName {get; set;}

 Professor(string ID, string firstName, string lastname)
  {
       this.id = ID;
       this.firstName = firstName;
       this.lastName = lastname;
  }

 //This method can be either static or not
 //Please note that i do not implement the ICloneable interface. There is discussion in the community it should be marked as obsolete because one can't tell if it's doing a shallow-copy or deep-copy
 public static Professor Clone(Professor original)
 {
   var clone = new Professor(original.id, original.firstName, original.lastName);
   return clone;
 }
}

//not a method, but a constructor for Course
public Course (string courseCode, string courseTitle, Professor teacher)
{
    this.courseCode = courseCode;
    this.courseTitle = courseTitle;
    this.teacher = Professor.Clone(teacher)

}

【问题讨论】:

  • 您需要深度克隆您的教授实例。还有更多帮助吗?
  • @我如何深度克隆它?你能修改我的教授实例并给我看吗?
  • @LuisFilipe - 非常感谢
  • 什么是防御性副本?
  • @Aron 提问者将我们指向javapractices.com/topic/TopicAction.do?Id=15

标签: c# defensive-copy


【解决方案1】:

您可以克隆您的教授实例。

克隆逻辑应该在Professor 类中。

然后您可以在Course 构造函数中接收已克隆的教授实例

public class Professor
{
 public string id {get; set; }
 public string firstName{get; set;}
 public string lastName {get; set;}

 Professor(string ID, string firstName, string lastname)
  {
       this.id = ID;
       this.firstName = firstName;
       this.lastName = lastname;
  }

 //This method can be either static or not
 //Please note that i do not implement the ICloneable interface. There is discussion in the community it should be marked as obsolete because one can't tell if it's doing a shallow-copy or deep-copy
 public static Professor Clone(Professor original)
 {
   var clone = new Professor(original.id, original.firstName, original.lastName);
   return clone;
 }
}

然后,当您调用新的 Course 时,您将执行此操作

public Course AddCourse(string courseCode, string courseTitle, Professor original)
{
  var clonedProfessor = Professor.Clone(original);
  var course = new Course(courseCode, courseTitle, clonedProfessor);
  return course;
}

【讨论】:

  • 现在,在课堂之外对教师对象所做的任何更改都不会反映在课程对象上,对吗? Course 对象真的是不可变的吗?
  • 您必须将这些对象视为指针(引用)。当你克隆一个教授时,你有两个不同的教授,它们恰好具有相同的属性值。如果您随后更换一位教授,另一位教授将不会改变
  • @Sebas 我同意并将删除它
  • 我的懒惰说只是序列化Professor 实例,将其保存为Course 中的纪念品,并在发生灾难时对其进行补充。您选择的 json 或 xml...
  • 我可以从课程构造函数内部调用Professor.Clone,而不是在课程中使用AddCourse 方法吗?为什么你删除了另一种创建防御副本的方法?
猜你喜欢
  • 2016-05-22
  • 2011-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多