为什么我需要使用get和set?

时间:2011-11-01 14:09:00

标签: c# .net oop encapsulation

我有一段代码:

public class MyClass
{
    private string _myProperty;

    public string MyProperty
    {
        get
        {
            return _myProperty;
        }

        set
        {
            _myProperty = value;
        }
    }
}

这里有什么意义?我本可以将_myProperty字符串声明为public,我的任何类对象都可以直接访问它们并获取或设置值。

相反,我们使用类对象将_myProperty设为私有,并使用get和set来访问它们。

在任何一种情况下,类对象都能够访问它们,结果总是相同的。

那么为什么要使用这种方法呢?那只是因为我可以在setter中实现一些约束吗?

除了会对会员变量造成什么危害?在这个例子中,我可以将_myProperty公开为公开,而不是仅仅通过将其设为私有来将其限制在此类,就像OOP所建议的那样。

5 个答案:

答案 0 :(得分:18)

不,结果不总是

  • 尝试绑定到公共字段(或执行任何其他使用反射并期望属性的内容)
  • 尝试通过引用传递属性(您不能
  • 稍后尝试 决定要进行日志记录等,并发现当您将其更改为属性时,会丢失源和二进制兼容性。

前一段时间阅读article I wrote on this ...

请注意,从C#2开始,您的代码可以缩短批次

public class MyClass
{
    public string MyProperty { get; set; }
}

答案 1 :(得分:1)

字段_myProperty是一个实现细节 - 它告诉编译器你想要一些字符串引用存储并给它那个名字。 get / set方法是对象属性的一部分,它抽象了如何 MyProperty属性的实现。因此,如果您想要更改字符串的存储/检索方式,第三方依赖者不必重新编译。

您还可以使用自动属性为您执行此操作:

public string MyProperty {get; set;}

答案 2 :(得分:1)

如果您只是将变量声明为Public,则这些实际上不是Properies。许多使用反射的功能都不起作用,特别是DataBinding,Serialization等。

偶尔我会变得懒惰并且这样做,特别是在VB.Net pre v4中工作,因为没有自动属性,并且总是后悔并返回正确编写属性。

如果您的类要由您自己以外的开发人员编写的代码使用,那么使用属性尤其重要,因为他们可能会遇到因不编写完整属性而产生的限制问题。

答案 3 :(得分:0)

正如您所说,属性的主要原因是验证。每个班级都有责任保证他们的成员安全,_myProperty是MyClass的成员。 .Net实现这一责任的方式是有道理的。在Java中,您必须定义两个方法:SetMyPropety和GetMyProperty。

答案 4 :(得分:0)

重要的是要注意虽然类通常有助于在属性中包装字段,但对于结构来说这通常会适得其反。关于结构使用的许多建议限制源于假设所有结构域都将包含在属性中。如果结构的语义提供:

  1. 其状态完全由固定数量的参数定义,所有参数都公开暴露用于阅读。
  2. 可以自由地为这些参数分配对其各自类型合法的任何值组合。
  3. 将结构的默认实例指定为将所有参数初始化为其各自类型的默认值。

然后公开字段会暴露数据类型的“内部工作”,但是这种曝光不会排除对数据类型的任何有意义的未来更改,这些更改尚未被规范排除。存储在可修改位置的所有结构的所有字段都始终暴露用于变异,即使唯一的变异方式是从一个实例到另一个实例的所有公共和私有字段的批量副本。如果结构的语义要求代码能够创建一个实例,其定义参数具有值的任意组合,而没有限制,直接暴露结构的字段将不允许单线程代码执行任何无法执行的操作慢慢没有这样的访问。暴露字段的唯一事情将允许代码执行,否则它将无法执行:

  1. 执行得更快
  2. 更清楚地表达其意图
  3. 在多线程场景中定义了语义,否则语义会变得模糊不清
对于要求类型的消费者运行速度较慢,写得笨拙,并且具有模糊的多线程语义,我并没有看到太多好处。

请注意,如果有一个策略反对使用具有变异'this'的属性的结构,而不是封装所有结构字段的策略,那么语句如:

myListOfPoint[4].X = 5;
即使语言允许在只读结构上调用属性设置器,也会拒绝

(假设目的是用于

这样的目的)
myArraySegment[3] = 9;

将被理解为访问myArraySegment拥有引用的数组。