封装 C# 新手

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却没有任何内容,这不就等于把你的私有后备字段声明为公共的吗?如果你可以直接从外部获取和设置它,为什么不直接这样做呢?

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

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


这是5个绝对精彩的答案。谢谢大家! - Gia Sadhwani
优美的回答方式! - Irf

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 库,更新就会变得更加棘手。


2
通过使用 public string MyName { get; set; },您可以在不需要重新编译/更改使用属性的其他代码的情况下,在以后改变它的逻辑。例如,如果您正在制作一个库,并且 v1 使用字段而 v2 使用属性,则使用 v1 的应用程序将无法在不重新编译(并且可能在某些 .NET 语言中编写的代码更改访问字段的语法)的情况下与 v2 一起工作。另一个重要的区别在于序列化场景--其中很多都不支持字段。此外,任何需要属性的接口都不能在没有使用属性的情况下实现,但根据接口,可能不需要在其中执行任何附加检查/逻辑。

0

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

public string MyName { get; private set; }

此外,属性在其他场景中也被用于诸如DataContract和Serialization等情境中... 所以,这是一个不错的特性...(大多数情况下,是一种语法糖。我认为)编辑:我收回之前的说法..您可以对其应用虚拟,所以它并不相同。

0

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接