以下是什么风险?如何重写它以使其更安全?

时间:2013-06-14 18:18:41

标签: c#

你会如何回答这个面试问题?

以下内容有什么危险?如何重写以使其更安全?

class Line {public Point p1; public Point p2; public double length;}

谢谢,

3 个答案:

答案 0 :(得分:3)

如果长度成员的意图是提供线的长度,则风险是可以改变长度而不考虑真实的线路长度。点之间的距离。

有很多方法可以解决这个问题。这是一个:

class Line {
  public Point p1;
  public Point p2;
  public double length {
     get {
        return ....
     }
  }
}

这样,每次访问时都会计算距离,并且只读取该距离,因此可以防止引入不一致的更改

答案 1 :(得分:1)

  1. 首先,你没有在类上设置一个显式修饰符,所以你最终将会遇到默认情况(如果它在命名空间中,那么internal或{{ 1}}如果包含在一个类中)。这可能会在编译时造成轻微的不便。更大的问题可能是默认情况下,类会使类超出预期范围,在这种情况下,您可能会无意中允许更多地访问类,而不是预期的类。无论如何,初学者或中等C#程序员很难看清楚这一点,知道会发生什么,这可能是一个可维护性问题。

  2. 但最大的问题是所有的课堂领域都被公之于众。通常,您希望使用属性来公开字段:限制读/写能力,通过反射使字段更容易被发现,执行验证等。这导致......

  3. 您可以看到该类名为“Line”,并显示它的点和它的长度。调用者当前可以轻松更改任何这些值,但其他值不会更新。长度应该是计算属性(只读),因为更改长度会产生不可预测的结果(哪个点会改变?)。

    所以我会把这个类重写为:

    private
  4. 如果有多个线程一起工作,或者即使在两个对象引用同一个Line实例并且一个对象可能不知道另一个更改(因此导致问题)的简单情况下,此类的可变性可能会导致问题)。如果可变性是一个问题,那么所有属性都应该是只读的:

    public class Line
    {
        public Point P1 {get;set;}
        public Point P2 {get;set;}
        public double Length
        {
            get
            {
                return Math.Sqrt( 
                    Math.Pow( P2.X - P1.X, 2 ) + 
                    Math.Pow( P2.Y - P1.Y, 2 ) 
                );
            }
        }
    }
    

答案 2 :(得分:1)

所有成员都应该是属性getter / setter。支持成员/字段是可选的 例外是Length属性。您不希望长度修改独立于线特征 - 例如不考虑使该属性为只读的点坐标。

class Line {
   private Point _startPoint;
   private Point _endPoint;

   public double Length {
      get { return _startPoint.X - _endPoint.X; } // modify for your own algorithm
   }

   // add public property setters for Start and End Points
}

这可以防止最终开发人员或消费者应用程序独立于行坐标修改长度。

注意:
一条线似乎是一个值类型,可以是一个结构。