【问题标题】:Maintaining encapsulation with properties and methods使用属性和方法维护封装
【发布时间】:2014-08-14 21:23:17
【问题描述】:

如果我有如下课程:

public class Name
{
    public String FirstName { get; set; }
    public String LastName { get; set; }

    public String FullName()
    {
        return FirstName + " " + LastName;
    }
}

FullName() 连接名字和姓氏,因此将其作为方法是有意义的。假设我更改了类的工作方式,因此它将全名存储为字符串,FirstName 和 LastName 返回子字符串。那么 FirstName 和 LastName 是方法和 FullName 是一个属性是有意义的。我阅读了these guidelines 关于在哪里使用属性的内容,其中指出属性不应相互依赖。

使用属性和方法不会破坏封装,因为这意味着您将内部实现细节暴露给外部代码?

在这种情况下,您不想公开存储了哪些值以及派生了哪些值,您应该怎么做?大概它们都应该是方法,或者它们都应该是属性,但哪个?

【问题讨论】:

  • 为什么不把 FullName 设为仅使用 getter 的属性,第一个和最后一个全名和子字符串似乎是一个非常糟糕的主意,因为您如何知道子字符串的位置(想想连字符的名称)
  • 我一直以为properties就是为了这个。
  • @sa_ddam213 我在第 2 点中阅读的here 的准则指出属性不应相互依赖。那有错吗?
  • 它们是指导线而不是事实线
  • 我很确定这不会产生相互依赖关系,因为FullName 属性没有设置器。相互依赖是指您有多个 setter 来修改相同的基础数据。在假设的示例中,您只能通过一次分配修改一条数据。

标签: c# properties encapsulation


【解决方案1】:

属性是否应该独立存在争议。

我会说,在你的情况下,拥有财产

public String FullName { get { return FirstName + " " + LastName; } } // no set

看起来可以接受。

与 .NET Rectangle.Bottom 属性比较,后者返回两个其他属性的总和

这个矩形的 Y 和高度之和的 y 坐标。

【讨论】:

  • 我觉得这里“相互依赖”这个词的用法有点松散。
  • @JoshuaShearer :-) 我回答了您对该问题的评论,然后阅读了这篇文章。我同意,“相互依存”一词是松散的。但是请参阅页面中的第二点。它似乎解决了简单的依赖关系。
  • 我同意。虽然,我发现他的指导方针有点错误。没有设置器的属性几乎保证依赖于另一个;在我看来,这绝对没有错。
  • @JoshuaShearer 我完全同意。此外,我什至认为真正的相互依赖没有根本问题(尽管它可能需要一点准确性,并且可能会增加额外的使用约束)。如果属性是正交的,我会说这很方便,但根本不是必须的。
【解决方案2】:

如果您想严格遵循这些准则,那么我将为 First name 和 Last name 创建完整的属性,并在 FullName 上对私有字段使用 get only 访问器,因为他的准则只提到属性依赖项而不是字段依赖项。

我假设这些指南是基于逻辑可以在 getter 和 setter 中执行的事实,采用现场路线将消除这种风险

例子:

public class Name 
{
    private string _firstName;
    private string _lastName;

    public string FirstName
    {
        get { return _firstName; }
        set { _firstName = value; }
    }

    public string LastName 
    {
        get { return _lastName; }
        set { _lastName = value; }
    }

    public string FullName
    {
        get { return _firstName + " " + _lastName; }
    }
}

【讨论】:

  • 似乎违反了准则中的第二项,因为设置一个属性会影响另一个属性。
  • 不是真的,Fullname 不依赖于 First 或 LastName 属性,但它位于支持字段上,我的假设是在某些情况下,setter/getter 中可能存在数据库逻辑等,确保您仅从支持字段中提取最后一个设置值应该减少对任何 setter/getter 逻辑(如果存在)的依赖,但如果指南打算您不能在属性中返回多个字段,那么 Microsoft 需要学习遵循此人的指南,如果这是一个问题,因为它非常常见,如果 MS 这样做,IMO 比一些 c#“专家”指南更有效。
  • 我的意思是指导方针说(我不同意顺便说一句):“它们不应该相互依赖。请注意,这将包括设置一个属性并让它影响另一个属性。" 设置FirstName 肯定会影响FullName
  • 我看待它的方式是 FullName 取决于字段的值而不是 Properties get set 逻辑(我认为这是他试图传达的点),我想这取决于如何你解释这些荒谬的指导方针:)
猜你喜欢
  • 2011-02-23
  • 1970-01-01
  • 2011-04-16
  • 2012-12-07
  • 2011-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-19
相关资源
最近更新 更多