C# 使用属性和方法维护封装

C# 使用属性和方法维护封装,c#,properties,encapsulation,C#,Properties,Encapsulation,如果我有如下的课程: public class Name { public String FirstName { get; set; } public String LastName { get; set; } public String FullName() { return FirstName + " " + LastName; } } FullName()将名字和姓氏连接在一起,因此将其作为方法是有意义的。假设我更改了类的工作方式

如果我有如下的课程:

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作为属性是有意义的。我读了关于在哪里使用属性的文章,其中指出属性不应该相互依赖

使用属性和方法是否会破坏封装,因为这意味着您将向外部代码公开内部实现细节


在这样的情况下,如果您不想公开哪些值是存储的,哪些是派生的,您应该怎么做?假设它们都应该是方法,或者它们都应该是属性,但是属性是否应该是独立的是有争议的

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

public String FullName { get { return FirstName + " " + LastName; } } // no set
看起来可以接受

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

y坐标,即此矩形的y和高度之和


如果您想严格遵守这些准则,那么我将为First和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; }
    }
}

为什么不使用getter将
FullName
也作为一个属性,将FullName和子字符串作为第一个和最后一个字符串似乎是一个非常糟糕的主意,因为如何知道子字符串的位置(想想连字符的名称)我一直认为这就是我们的目的。@sa_ddam213我在第2点中读到的指南说明属性不应该相互依赖。那么这是错的吗?它们是指导线而不是事实线我很确定这不会产生相互依赖性,因为
FullName
属性没有setter。相互依赖性是指当您有多个setter修改相同的基础数据时。在这个假设的例子中,你只能用一个赋值修改一段数据。我认为“相互依赖”一词在这里的用法有点松散。@JoshuaShearer:-)我回答了你对这个问题的评论,然后读了这个。我同意,“相互依存”一词是松散的。但请看本页的第二点。我同意,这似乎解决了普通的依赖问题。尽管如此,我还是觉得他的指导方针有点错误。没有setter的属性几乎保证依赖于另一个属性;“在我看来,这绝对没有错。”约书亚·希勒我完全同意。此外,我甚至认为真正的相互依赖性没有根本问题(尽管它可能需要一点准确性,并且可能会增加额外的使用约束)。我想说,如果属性是正交的,这是很方便的,但这根本不是必须的。指南中的第二项似乎被违反了,因为设置一个属性会影响另一个属性。事实并非如此,Fullname不依赖于First或LastName属性,但它位于支持字段上,我的假设是,在某些情况下,setter/getter中可能存在db logic etc,确保您仅从备份字段中提取最后一个设置值,这将减少对任何setter/getter逻辑(如果存在)的依赖性,但是,如果该指导方针打算您不能在一个属性中返回多个字段,那么Microsoft需要学习遵循此人员指导方针,如果这是一个问题,因为它非常常见,IMO如果MS这样做,它比一些c#“专家”指导方针更有效。我的意思是,该指导方针说(顺便说一句,我不同意):“它们不应该相互依赖。请注意,这将包括设置一个属性并使其影响另一个属性。“设置
FirstName
肯定会影响
FullName
。我看FullName的方式取决于字段的值,而不是属性get set逻辑(我假设这是他试图传达的点),我想这取决于你如何解释这些荒谬的指导原则:)