C#: 我可以移除 "{ get; set; }" 吗?

5

这两者之间有什么区别:

public T RequestedValue { get; set; }

并且。
public T RequestedValue;

从这段代码中获取:

public class PropertyChangeRequestEventArgs<T>:EventArgs
{
    public PropertyChangeRequestEventArgs(T pRequestedValue)
    {
        RequestedValue = pRequestedValue;
    }

    public T RequestedValue { get; set; }
}

可能是重复的问题: 什么是 C# 中字段和属性的区别? - nawfal
4个回答

23

第一个是自动实现属性,第二个是字段。常规的属性会公开Getter和Setter,但还有一个私有字段来实际存储值:

private int someProperty;
public int SomeProperty
{
    get { return someProperty; }
    set { someProperty = value; }
}
第一种方式允许你在不影响应用程序中的所有其他代码的情况下改变类的某些实现方面。最重要的是,使用属性可以进行更改而不会破坏二进制兼容性(虽然字段通常可以更改为属性而不破坏代码)。如果它是公共成员,则建议使用属性。(大胆地从 Snarfblam 的评论中复制) 从“Properties”页面中得知:
属性是成员,提供了一种灵活的机制来读取、写入或计算私有字段的值。属性可以像公共数据成员一样使用,但它们实际上是称为访问器的特殊方法。这使得数据可以轻松地访问,并仍然有助于促进方法的安全性和灵活性。
具有后备字段的属性是最灵活的形式,因为它们允许轻松实现诸如在 Model-View-ViewModel 实现中更新 UI 的 INotifyPropertyChanged 事件等内容。

7
我认为最重要的一点是,通过属性进行更改时可以保持二进制兼容性(尽管字段通常可以更改为属性而不会破坏代码)。如果它是一个公共成员,建议使用属性。 - snarf
@Snarfblam - 这就是我想说的,你不介意我抄袭吧? - ChrisF
@Snarfblam,你通常可以更改它而不会破坏代码,但是可能会破坏依赖于它的现有可执行文件和库。这些需要重新编译。 - Dykam
1
请记住,属性相对于字段具有其他优势。某些属性只能放置在属性上而不能放置在字段上。并且有一些(至少曾经)数据绑定方案无法使用字段。 - Rob

3

深入解释!

{get; set;} 是一个自动属性,而第二个是一个字段。

字段是一种常规变量,来自某种类型,包含数据。

属性是一对方法(有时只有一个),一个用于获取,一个用于设置。它们仅具有类似字段的语法,但实际上它们非常不同。

属性通常用于过滤值的集合或在获取中虚拟一些东西等。

自动属性还会在幕后创建一个私有字段,在获取中返回其值,在设置中设置其值。

表面上看这就像一个普通的字段,但在幕后(IL)使用属性与使用字段完全不同。

 a.Property1 = 4;

is translate into something like:

 a.Set_Propert1(4);

并且这个:

x = a.Property1;

翻译成中文大概是这样的:

x = a.Get_Property1();

那么为什么只使用公共属性是一个好的实践呢,即使它们是自动的?

假设你正在编写一个库,该库被其他应用程序使用,而有一天你想发布该库的新版本,限制其中一个类的字段。

如果你使用属性,你可以只更改属性(即使它是自动属性,你也可以将其替换为完整属性),然后任何使用你的库的应用程序仍然可以以相同的方式使用它。

但是,如果你创建了一个公共字段,并且现在想要限制它,你需要为此创建一个属性并将该字段设置为私有。但是,如果你这样做,任何使用你的库的应用程序都将无法再使用它,因为它使用字段和属性的方式不同。


1

你可以写:

public T RequestedValue { get; set; }

作为的快捷方式:

private T _requestedValue;

public T RequestedValue
{
  get { return this._requestedValue; }
  set { this._requestedValue = value; }
}

它们是完全等价的,而且性能也相同。


这不是回答问题。 - Letterman
我知道这不是回答问题,因为第一个回答(ChrisF)已经很好地回答了差异。我只想补充一下属性简洁语法的准确性。 - venezia

0
答案是,可以删除 { get; set; },但接下来会有很多微妙的差异。一些人会说字段和属性表达了根本不同的设计意图,但实际上随着 C# 的发展,这种区别逐渐被侵蚀,并逐渐模糊了语法上的差异。
要了解字段和属性之间在编译器二进制级别的差异列表,请参考 SO 问题 difference-between-property-and-field-in-c。但是那个问题的答案错过了一个关于在声明接口时属性的特殊角色的重要点。

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