封装C#新手

本文关键字:新手 封装 | 更新日期: 2023-09-27 18:22:45

C#新手,我理解封装只是"保护数据"的一种方式。但我仍然不清楚。我认为获取和设置访问器的是在这些方法中添加测试,以检查参数是否符合某些标准,然后允许外部函数获取和设置任何东西,比如:

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; }

为什么你会在什么都没有的情况下就这样一筹莫展,这不就是宣布你的私人支持领域是公开的吗?如果你可以从外面得到并设置它,为什么不直接做呢?

封装C#新手

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

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; }

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

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

例如,如果您正在创建一个库,而v1使用一个字段,v2使用一个属性,那么在不重新编译的情况下,使用v1的应用程序将无法使用v2(如果代码是用某些.NET语言编写的,并且这些语言具有不同的访问字段语法,则可能会发生代码更改)。

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

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

如果你有一个类:

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方法:

CCD_ 2和CCD_ 3

因此,这两种方法确实产生了不同的编译代码。现在,如果所有使用此类的代码都在同一个项目中,那就没什么大不了的了,因为它们都将一起编译。但是,如果您已经分发了一个API库,那么更新它可能是一件更大的事情。

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

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

是的,但您可以很容易地将其更改为:

public string MyName { get; private set; }

此外,属性还用于其他场景,如DataContracts和序列化。。。所以,这是一个很好的功能。。。(主要是语法糖。我想)编辑:我收回了。。您可以将virtual应用于它,因此它与不同