简体   繁体   English

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

[英]Why do I need to use get and set?

I have a code segment: 我有一个代码段:

public class MyClass
{
    private string _myProperty;

    public string MyProperty
    {
        get
        {
            return _myProperty;
        }

        set
        {
            _myProperty = value;
        }
    }
}

What is the point here? 这有什么意义? I could have declared the _myProperty string as public and any of my class objects will be able to directly access them and get or set the value. 我可以将_myProperty字符串声明为public,我的任何类对象都可以直接访问它们并获取或设置值。

Instead, we are making _myProperty private and the using get and set to access them, using the class object. 相反,我们使用类对象将_myProperty私有,并使用get和set来访问它们。

In either case, the class object is able to access them and the result is always same. 在任何一种情况下,类对象都能够访问它们,结果总是相同的。

So why use this approach? 那么为什么要用这种方法? Is that only because I can implement few constraints in setter? 那只是因为我可以在setter中实现一些约束吗?

Apart from that what harm will making member variables public cause? 除此之外会对成员变量造成什么危害呢? In this example I could expose _myProperty as public instead of restricting it to this class only by making it private, as OOP would suggest. 在这个例子中,我可以将_myProperty公开为public,而不是像OOP所暗示的那样将它限制在这个类中。

No, the result isn't always the same. 不,结果并不总是一样的。

  • Try binding to a public field (or doing anything else which uses reflection and expects properties) 尝试绑定到公共字段(或执行任何其他使用反射和期望属性的字段)
  • Try passing a property by reference (you can't) 尝试通过引用传递属性(你不能)
  • Try later deciding you want logging etc and finding that when you change it to a property, you lose both source and binary compatibility. 稍后尝试确定您希望记录等,并发现当您将其更改为属性时,您将失去源和二进制兼容性。

Read the article I wrote on this a while ago... 阅读我刚才写这篇文章 ......

Note that as of C# 2 your code can be a lot shorter though: 请注意,从C#2开始,您的代码可以缩短很多

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

The field _myProperty is an implementation detail—it tells the compiler you want some storage for a string reference and to give it that name. 字段_myProperty是一个实现细节 - 它告诉编译器你想要一些字符串引用的存储并给它那个名字。 The get/set methods are part of the property of the object, which abstracts how the MyProperty property is implemented. 该get / set方法是对象,抽象出怎样的财产的一部分MyProperty属性来实现。 So, say, if you want to change how the string is stored/retrieved, 3rd-party dependants don't have to re-compile. 因此,如果您想要更改字符串的存储/检索方式,第三方依赖者不必重新编译。

You can also use automatic properties to do this for you: 您还可以使用自动属性为您执行此操作:

public string MyProperty {get; set;}

If you just declare variables as Public , these are not actually Properies. 如果您只是将变量声明为Public,则这些实际上不是Properies。 Many of the functionalities that use reflection will not work, in particular DataBinding, Serialization and so on. 许多使用反射的功能都不起作用,特别是DataBinding,Serialization等。

Occasionally I get lazy and do this, particularly when working in VB.Net pre v4 as there are no auto properties, and always regret it and go back to write the properties in properly. 偶尔我会变得懒惰并且这样做,特别是在VB.Net pre v4中工作时,因为没有自动属性,并且总是后悔并返回正确编写属性。

It is especially important to use properties if your class is to be consumed by code written by developers other than yourself, as they may well have problems with the limitations imposed by not coding full properties. 如果您的类要被非自己的开发人员编写的代码使用,那么使用属性尤为重要,因为他们可能会遇到因不编码完整属性而产生的限制问题。

It's important to note that while it is often helpful for classes to wrap fields in properties, it is often counterproductive for structures to do so. 重要的是要注意,尽管类通常有助于在属性中包装字段,但对于结构来说这通常会适得其反。 Many of the recommended limitations on the use of structures stem from a presumption that all struct fields will be wrapped in properties. 关于结构使用的许多建议限制源于假设所有结构域都将包含在属性中。 If the semantics of a struct provide that: 如果struct的语义提供:

  1. Its state is completely defined by a fixed number of parameters, all of which are publicly exposed for reading. 它的状态完全由固定数量的参数定义,所有参数都公开暴露用于阅读。
  2. Those parameters may be freely assigned any combination of values that are legal for their respective types. 这些参数可以自由分配对其各自类型合法的任何值组合。
  3. The default instance of the struct is specified as having all parameters initialized to the default values of their respective types. 结构的默认实例被指定为将所有参数初始化为其各自类型的默认值。

then exposing fields would expose the "inner workings" of the data type, but such exposure would not preclude any meaningful future changes to the data type which would not already be excluded by the spec . 然后暴露字段将暴露数据类型的“内部工作”,但是这样的曝光不会排除对数据类型的任何有意义的未来更改,这些更改将不会被规范排除 All fields of all structs that are stored in modifiable locations are always exposed for mutation, even if the only means of mutation is a bulk copy of all public and private fields from one instance to another. 存储在可修改位置的所有结构的所有字段总是暴露出来进行变异,即使唯一的变异方法是从一个实例到另一个实例的所有公共和私有字段的批量副本。 If the semantics of a struct require that code be able to create an instance whose defining parameters have any combination of values, without restriction, exposing a struct's fields directly won't allow single-threaded code to do anything which it couldn't do more slowly without such access. 如果结构的语义要求代码能够创建一个实例,其定义参数具有值的任意组合,而没有限制,直接暴露结构的字段将不允许单线程代码执行任何无法执行的操作慢慢没有这样的访问。 The only things exposing the fields will allow code to do which it wouldn't be able to do otherwise are: 暴露字段的唯一事情将允许代码执行,否则它将无法做到:

  1. execute faster 执行得更快
  2. express its intention more clearly 更清楚地表达其意图
  3. have defined semantics in multi-threading scenarios where the semantics would otherwise be murky 已经在多线程场景中定义了语义,否则语义会变得模糊不清
I don't really see much benefit to requiring consumers of a type to run slower, be written awkwardly, and have murky multi-threading semantics. 我并不认为要求类型的消费者运行速度较慢,写得笨拙,并且具有模糊的多线程语义。

Note that if there were a policy against having structs with properties that mutate 'this', rather than a policy of encapsulating all struct fields, then a statement like: 请注意,如果存在一个策略,不允许使用具有变体'this'的属性的结构,而不是封装所有结构字段的策略,那么语句如下:

myArraySegment[3] = 9;

would be rejected even if the language allowed property setters to be called on read-only structs (with a presumption that the purpose would be for things like 即使语言允许在只读结构上调用属性设置器,也会被拒绝(假设目的是为了像

 myArraySegment[3] = 9; 

which would be understood as accessing the array to which myArraySegment holds a reference). 这将被理解为访问myArraySegment包含引用的数组。

As you said the main reason for properties is validation. 正如你所说,属性的主要原因是验证。 Every class has this responsibility to keep their memebers safe and _myProperty is a member of MyClass. 每个班级都有责任保证他们的成员安全,_myProperty是MyClass的成员。 The .Net's way for implementing this responsibility is propety. .Net实现这一责任的方式是有道理的。 in Java you have to define two methods: SetMyPropety and GetMyProperty. 在Java中,您必须定义两个方法:SetMyPropety和GetMyProperty。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM