【问题标题】:Public accessor .net公共访问者.net
【发布时间】:2010-12-29 18:51:18
【问题描述】:

我认为是在 .net 2.0 中,微软引入了一个访问器,缩写为类似

public string Name { get; set; }

但是上面的代码有什么真正的区别吗,简单来说:

public string Name;

【问题讨论】:

标签: c#


【解决方案1】:

主要区别在于,如果您以后需要在 getter 或 setter 中添加逻辑,并且其他 DLL 已经针对您的进行编译,您可以轻松更改

public string Name { get; set; }

进入

public string Name { get{/*special code*/} set{/*special code*/} }

发布新的 DLL 并且不重新编译其他 DLL 不会是重大更改。


如果你改变了

public string Name;

进入

public string Name { get{/*special code*/} set{/*special code*/} } 

那么您需要确保重新编译所有使用您的 DLL,因为它们从访问字段变为访问属性。

当您将 DLL 发送给其他程序员(例如作为开源项目或作为组件供应商)时,这显然是一个更大的问题,而不是您只是为自己/雇主构建应用程序

【讨论】:

  • 有趣,为什么在第二种情况下编译的代码不同。编译字段的目的是什么,以便一旦字段被属性替换,所有客户端都需要重建。
  • 因为在MSIL中,属性访问是一种特殊的方法调用,而字段访问只是字段访问。
  • 作为差异的示例:您可以将字段用作某些方法的“out”或“ref”参数,但不能对属性执行此操作。因此,如果您将其更改为属性,那么以这种方式使用该字段的代码将会中断。
【解决方案2】:

区别在于 FieldProperty。字段只是类实例上的成员变量。相比之下,属性是两个独立操作的简写 - get 和 set:

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

private string _name;

这是一个过于简单的示例,因为该属性只是通过在 getter 中返回私有字段并在 setter 中设置它来“包装”私有字段。但是,当属性成为通向基础价值的“门户”时,它们就变得非常有用。如果程序流程需要在每次设置字段的值时发生某些事情(例如,触发事件),则可以从属性的设置器中触发它:

set
{
    this.InvokePropertyChangedEvent();
    _name = value;
}

您所询问的确切语法称为 Auto-Implemented Properties,这只是我上面提供的简单示例的简写。编译器创建一个由属性获取和设置的私有成员。

【讨论】:

  • @Rex:但这不是所问的问题。问题在于声明之间的区别,而不是字段和属性之间的区别。
  • @curious 两个声明之间差异的完整解释需要我们不能假设 OP 已经拥有的背景信息。您正在寻找的短片在最后。
  • 我想在我的回答中写下引发事件,但那又不是问题。
  • @Rex:我们甚至不能假设他可能不知道!
  • @curious 我很惊讶你争辩说我在答案中提供的信息不太完整,因为 OP 可能 已经知道了。其他提出这个问题的人呢?
【解决方案3】:

自动属性最初是在 C# 3.0 中引入的。区别:

public string Name { get; set; }

public string Name;

是第一个声明property,而第二个声明field。在 OOP 中,属性用于封装字段。一个属性可以有 settergetter 或两者,您还可以为每个属性指定不同的可访问性级别。

【讨论】:

    【解决方案4】:

    就编写代码来获取值或存储值而言,没有功能上的区别。但是在某些情况下,调用者可能期望一个字段或一个属性,并且通过使用反射只接受一个或另一个。例如,WPF 可能只绑定到一个属性而不是一个字段。

    【讨论】:

      【解决方案5】:

      简写属性声明的区别在于可以这样定义。

      public string Name { get; private set; }
      

      这意味着可以公开读取属性,但只有私有成员可以写入。你不能为一个领域做这样的事情。

      如果你查看生成的 IL 速记财产声明,你 会发现编译器添加了 / 自动生成的成员字段到 属性将读取或写入。

      【讨论】:

      • 添加访问修饰符的能力很有意义。在 getter 和 setter 中多次使用不同的访问权限,但在速记声明中没有使用。也想知道这个问题,但懒得问。现在更清楚了。虽然如果有其他差异,我不会感到惊讶。
      【解决方案6】:

      是的,您在第二行中的代码直接使内存中的成员可用,而在第一行中,您有一个间接级别,您可以在将来添加一些逻辑来验证和延迟分配。

      此外,如果您使用反射,则必须在第一行示例中查找 Property Setter 和 Getter,而对于第二行,您需要直接检索成员变量。

      通常,使用属性是更好的设计。

      【讨论】:

        【解决方案7】:

        我为 propertygrid 用户发现的一个有用的区别是使用 公共字符串名称 { 获取;放; } 我们可以很容易地在 Propertygrid 中设置源数据。

        在声明时 公共字符串名称; 不会完全用于 Propertygrid。

        【讨论】:

          猜你喜欢
          • 2010-10-14
          • 1970-01-01
          • 2022-01-27
          • 1970-01-01
          • 2021-09-14
          • 2015-11-20
          • 1970-01-01
          • 2019-12-22
          • 1970-01-01
          相关资源
          最近更新 更多