C#基础制作属性原子

t3r*_*rse 9 c# design-patterns

它由Microsoft作为框架设计指南给出,属性应该彼此独立,而不是依赖于按任何特定顺序设置.

假设您有一个需要支持dimmensions和面积计算的三角形类.你会如何模仿这个?

这当然是被认为是gauche的设计,因为Area依赖于Base和Height首先设置:

class Triangle{
    public double Base {get;set;}
    public double Height {get;set;}
    public double Area {
        get{
            return (Base * Height) / 2;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

假设您使用构造函数,您可以确保此情况的默认值,但这是正确的方法吗?

class Triangle{
    public Triangle(double b, double h){
        Base = b;
        Height = h;
    }

    public double Base {get;set;}
    public double Height {get;set;}
    public double Area {
        get{
            return (Base * Height) / 2;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您仍然拥有一个依赖于其他属性的属性.为了成为一个纯粹主义者,我只能看到几种方法(我想它们可以合并):

  1. Make Base/Height具有只能在构造函数中设置的只读成员

  2. 将面积计算成方法.

  3. 使用某种工厂模式+ readonly成员来确保尽管可能存在依赖关系,但只能通过实例化Triangle类的方法来设置值.

问题:

  1. 指南是否切实可行(为了支持它,您是否必须在您的类中建立很多复杂性)?[例如,SqlConnection类允许您初始化连接字符串属性,但允许您更改它的各个部分,例如命令超时]

  2. 您如何管理保持您的财产彼此独立?

  3. 对于使用Silverlight/MVVM类型体系结构的人来说,由于数据绑定对象的工作方式,您是否接受属性中的依赖项?例如,绑定一个三角形实例,在屏幕上显示高度,基数和面积.

Rob*_*les 15

微软真的试图说"不要以这样的方式设计你的类,即以任意顺序调用属性会导致意外行为." 您班级的用户不希望请求值(使用属性)具有尴尬的副作用.

这属于最不意外的原则.

我认为这是一个完全实用的指南.属性不应该有意想不到的副作用.

你提出了一个很好的问题:"你如何管理保持你的财产彼此独立?".非常小心!我尽可能地消除状态(并相应地减少属性的数量).此外,通过分解类来分区状态是另一种策略.这本身就是一个很好的问题......

就三角形类而言,我认为您在代码中呈现的两种解决方案都是有效的.如果由我决定,我会设计三角形以使其不可变,并在构造函数中获取宽度和高度.