6

C# 新手,我知道封装只是“保护数据”的一种方式。但我仍然不清楚。我认为get 和 set 访问器的目的是在这些方法中添加测试以检查参数是否符合某些标准,然后再允许外部函数获取和设置任何内容,如下所示:

private string myName;
public string MyName;// this is a property, speical to c#, which sets the backing field.

private string myName = "mary";// the backing field.

public string MyName // this is a property, which sets/gets the backing field.
{
    get
    {
        return myName;
    }
    set
    {
        if (value != "Silly Woman"){ 
           myName = value;
        }

    } 
}

但我一直在 C# 中看到如下代码:

public string MyName { get; set; }

为什么你会有一个 get 和 set 里面什么都没有, - 这和只是宣布你的私人支持领域是一样的吗?如果您可以从外部获取和设置它,为什么不直接进行呢?

4

5 回答 5

7

实际上,创建一个自动属性如下:

public string Name { get; set; }

与构建由字段支持的属性相同:

private string _name;
public string Name {
    get { return _name; }
    set { _name = value; }
}

这些属性的重点不是隐藏数据。正如您所观察到的,他们不这样做。相反,这些属性可以做其他事情,而不仅仅是使用字段:

public string Name {
    get { return _name; }
    set { if (value == null) throw new Exception("GTFO!"); _name = value; }
}

另一件事是,您可以将属性设为虚拟

public virtual string Name { get; set; }

如果被重写,它可以在派生类中提供不同的结果和行为。

于 2013-07-16T03:00:52.927 回答
2

它使以后添加逻辑变得更加容易。如果你有一个类有一个公共字段,你想将其更改为一个属性,你必须重新编译所有使用你的类的东西。这是我最初不理解的关键点。

如果你有一堂课:

public class MyClass
{
    public string MyString;
}

您可以像这样访问值:

var myClass = new MyClass();
string s = myClass.MyString;

现在将其更改为属性:

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

它是如何访问的?完全相同的方式:

var myClass = new MyClass();
string s = myClass.MyString;

所以没什么大不了的,对吧?实际上....

属性实际上被编译成 getter 和 setter 方法:

get_MyString()set_MyString(string value)

所以这两种方法确实会产生不同的编译代码。现在,如果你所有使用这个类的代码都在同一个项目中,这没什么大不了的,因为它们都会被编译在一起。但是,如果您有一个已分发的 API 库,则更新可能会大得多。

于 2013-07-16T03:28:32.700 回答
2

通过使用public string MyName { get; set; },您可以在以后更改其逻辑,而无需重新编译/更改使用您的属性的其他代码。

例如,如果您正在创建一个库并且 v1 使用一个字段而 v2 使用一个属性,那么使用 v1 的应用程序在没有重新编译的情况下将无法使用 v2(并且,如果它们是用某些具有访问字段的不同语法)。

另一个重要的区别是在序列化场景中——其中很多不支持字段。此外,任何需要属性的接口都无法在不使用属性的情况下实现,但根据接口的不同,可能不需要在其中进行任何额外的检查/逻辑。

于 2013-07-16T03:04:04.527 回答
0

因为如果您想稍后添加检查/测试,更改代码会更容易。尤其是如果您的代码中有许多继承和许多类,则很难将实现从公共变量更改为公共属性。

此外,您可以在属性中添加不同属性的 get 和 set,例如,如果您使用反射。属性的 get 和 set 是内部不同的方法。如果您只有一个公共变量/字段,则无法将不同的属性添加到不同的访问方式。

于 2013-07-16T02:58:47.260 回答
0

是的,但是您可以轻松地将其更改为:

public string MyName { get; private set; }

另外,属性用于其他场景,如DataContracts 和序列化......所以,这是一个很好的功能......(主要是语法糖。我认为)编辑:我收回......你可以应用虚拟到它,所以不一样

于 2013-07-16T03:02:30.150 回答