为什么我们使用空白获取;放; C# 中的访问器?

发布于 2024-11-09 18:14:43 字数 375 浏览 0 评论 0原文

可能的重复:
c#:为什么有空获取设置属性而不是使用公共成员变量?

string name;

vs

string name {get; set;}

假设您的 get 和 set 如上所述为空,那么指定它们有什么意义?

Possible Duplicate:
c#: why have empty get set properties instead of using a public member variable?

string name;

vs

string name {get; set;}

Assuming your get and set are blank as above, what's the point in specifying them?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

献世佛 2024-11-16 18:14:44

它封装了编译器生成的字段,并为 classstruct 开发人员提供了稍后在内部更新它的能力,而无需通过简单地修改 get< 来破坏 API /code>/set 您关心的部分。

例如,突然不想返回 null ?您只需将空的 get 更改为 get { returnstoredName ?? 即可做到这一点。 “”; }。当然,这意味着您突然需要手动控制变量,但这是为灵活性付出的很小的代价。


第一个用途是 字段 声明的示例。第二种用途是自动实现的属性的示例。

提供对字段的直接访问通常是不好的做法。然而,.NET 团队注意到很多 getter/setter 基本上就是这样。例如,请考虑以下情况:

// C#
public string Name
{
    get { return name; }
    set { name = value; }
}

// Without properties (or a Java implementation)
public void setName(String name)
{
    this.name = name;
}

public String getName()
{
    return name;
}

无论哪种方式,实际上只是公开一个字段都非常冗长。然而,通常的情况是,作为开发人员,您需要返回并更改内部处理字段的方式,但您不想想要破坏甚至影响其他代码(如果可以的话)远离它。

这就是为什么直接访问字段是不好的。如果您提供对字段的直接访问,但需要更改有关使用该字段的某些内容,则使用该字段的所有代码也必须更改。如果您使用属性(甚至方法),那么您可以更改内部代码,并且可能不会影响外部代码。

考虑以下示例:

public string Name
{
    get;
    set;
}

稍后,您决定需要围绕 setter 引发更改和更改的事件。如果您暴露了一个字段,那么就可能需要进行一次大的重写。如果您使用属性(或方法),那么您只需在其中添加逻辑即可。您突然失去了自动实现属性的好处,但您获得了在不破坏现有代码的情况下重构类的能力。

private string name;
public event NameChangingEventHandler NameChanging;
public event NameChangedEventHandler NameChanged;

public string Name
{
    get { return name; }
    set
    {
        OnNameChanging(/*...*/);
        name = value;
        OnNameChanged(/*...*/);
    }
}

protected virtual void OnNameChanging(/*...*/) { }
protected virtual void OnNameChanged(/*...*/) { }

所有这些都维护您的公共 API,并且不需要该类的用户(您的代码的其余部分或使用您的 API 的外部开发人员)进行任何工作。重大更改并不总是可以避免的,但避免直接访问字段是尝试确保这种情况不会发生的一个很好的步骤。自动实现的属性是一种快速、简单的方法。

(无关:输入此内容时断电,我很高兴我的浏览器保存了大部分内容!)

It encapsulates the compiler generated field, and provides you, the class or struct developer the ability to update it internally later without breaking your API by simply modifying the get/set part that you care about.

For instance, suddenly never want to return null? You can do that by simply changing the empty get to get { return storedName ?? ""; }. Of course, it means you suddenly need to manually control the variable, but that's a small price to pay for the flexibility.


The first use is an example of a field declaration. The second use is an example of an auto-implemented property.

It is generally bad practice to provide direct access to a field. However, the .NET team noticed that a lot of getters/setters are basically just that. For example, consider the following:

// C#
public string Name
{
    get { return name; }
    set { name = value; }
}

// Without properties (or a Java implementation)
public void setName(String name)
{
    this.name = name;
}

public String getName()
{
    return name;
}

Either way, that's a lot verbosity to really just expose a field. However, it is regularly the case that, as a developer, you need to go back and change how a field is handled internally, but you do not want to break or even affect other code if you can get away with it.

That is why using direct access to fields is bad. If you provide direct access to fields, but need to change something about using the field, then all code that uses that field must change as well. If you use a property (or even a method), then you can change the internal code and potentially not effect external code.

Consider the following example:

public string Name
{
    get;
    set;
}

Later you decide that you need to raise a changing and changed event around the setter. If you exposed a field, then it's time for a potentially big rewrite. If you used properties (or a method), then you can just add the logic there. You suddenly lose the benefit of auto-implementing properties, but you gained the ability to refactor your class without breaking existing code.

private string name;
public event NameChangingEventHandler NameChanging;
public event NameChangedEventHandler NameChanged;

public string Name
{
    get { return name; }
    set
    {
        OnNameChanging(/*...*/);
        name = value;
        OnNameChanged(/*...*/);
    }
}

protected virtual void OnNameChanging(/*...*/) { }
protected virtual void OnNameChanged(/*...*/) { }

All of that maintains your public API and requires no work from users of the class (the rest of your code, or external developers using of your API). Breaking changes are not always avoidable, but avoiding direct access to fields is a good step to try to ensure that it won't happen. Auto-implemented properties are a quick, and easy way to do it.

(Unrelated: lost power while typing this and I am very happy that my browser saved most of it!)

萌酱 2024-11-16 18:14:44

第一个实际上是 Field,但第二个是自动实现的属性。它们之间的区别已经讨论过

The first one is actually a Field, but the second one is an Auto-Implemented property. The difference between them has already been discussed.

扎心 2024-11-16 18:14:44

第一个假设是在类作用域中声明的,它是一个字段名称。它作为字段进行访问。第二个是财产。空白获取/设置称为自动属性。

The first, assuming it's declared in class scope, is a field name. It's accessed as a field. The second is a property. A Blank get/set is known as an auto-property.

卸妝后依然美 2024-11-16 18:14:44

将来您可能需要在访问器中实际执行一些操作。将字段(这是您的第一个声明)更改为属性是一项重大更改,因此提前指定访问器对未来来说是一项很小的投资。

You might need to actually do something in your accessors in the future. Changing a field (which is what your first declaration is) to a property is a breaking change, so specifying accessors in advance is a small investment in the future.

穿越时光隧道 2024-11-16 18:14:44

能够在不破坏兼容性的情况下向字段的访问器添加逻辑是标准解释,如果您正在编写一个库或一个分为多个可能独立更新的程序集的库或应用程序,那么这肯定是一个很大的问题。我认为,如果您正在开发任何类型的“一体化”软件,那么人们可以忽略这一点,因为无论如何它都会被重新编译。

但即便如此,还有另一个非常令人信服的理由只在公共接口中公开属性:即使您永远不需要进行任何内部更新,使用字段仍然可能导致其他问题,因为 .NET 框架的许多部分与字段相比,强烈喜欢属性。例如,WPF 通常不支持绑定到字段。您可以通过执行 ICustomTypeDescriptor 之类的奇特操作来解决这个问题,但只需键入 {get; 就容易多了。放;}。

Being able to add logic to a field's accessors without breaking compatibility is the standard explanation, and it's certainly a big one if you're writing a library or an application that's split among several assemblies that might be updated independently. I think it's something that one could dismiss as less of a concern if you're working on any sort of "all-in-one" software, though, since it'll all be recompiled anyway.

But even then, there's still another very compelling reason to only expose properties in your public interfaces: Even if you never need to make any internal updates, using fields can still lead to other problems on down the line because many portions of the .NET framework strongly prefer properties to fields. WPF, for example, does not generally support binding to fields. You can get around that by doing fancy things like implementing ICustomTypeDescriptor, but it's just so much easier to simply type {get; set;}.

蹲在坟头点根烟 2024-11-16 18:14:44
string name {get; set;}

这称为自动实现的属性。实际上,C# 创建以 _ 本身开头的变量,因此在 get 时,会获取该变量值;在 set 时,会设置该变量值。它就像普通属性一样。其中 string name; 只是一个字段。

string name {get; set;}

This is called auto implemented property. Actually, C# creates variable starting with _ itself, so on get, that variable value is fetched and on set, that variable value is set. Its just like normal properties. Where as string name; is just a field.

懒猫 2024-11-16 18:14:44

第一个是变量,第二个是(简写)属性

The first is a variable, the second is a (shorthanded) property

巡山小妖精 2024-11-16 18:14:44

属性非常好,但作为一般规则,对象不应该向公众公开状态;从外人的角度来看,它们应该是一个黑匣子。而且您尤其不应该声明直接更改。状态应该作为要求对象实例在问题域中做一些有用的事情的副作用而改变。

如果要公开状态,请将其公开为只读属性(例如 public widget Foo { get ; private set ; })。

Properties are very nice, but as a general rule, objects shouldn't expose state to the public; they should be a black box from the perspective of outsiders. And you especially shouldn't state to direct change. State should change as a side effect of asking the object instance to do something useful in the problem domain.

If you are going to expose state, expose it as a read-only property (e.g. public widget Foo { get ; private set ; }).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文