53

我对 C# 中的自动属性点有点困惑,例如

public string Forename{ get; set; }

我知道您通过不必声明私有变量来节省代码,但是当您不使用任何获取或设置逻辑时,属性的意义何在?为什么不直接使用

public string Forename; 

我不确定这两个语句之间的区别是什么,我一直认为如果你想要额外的 get/set 逻辑,你会使用属性?

4

11 回答 11

118

属性可以在不破坏合同的情况下将代码放入其中,字段不能在不将其更改为属性(并破坏接口)的情况下将代码放入其中。属性可以只读或只写,字段不能。属性可以是数据绑定的,字段不能。

于 2009-08-18T15:34:43.563 回答
15

你可以写

public string Forename{ get; private set; }

获得只读属性...仍然不像真实属性那样通用,但对于某些作品来说这是一种折衷方案。

于 2009-08-18T15:36:23.607 回答
12

我不确定这两个语句之间的区别是什么,我一直认为如果你想要额外的 get/set 逻辑,你会使用属性?

在第一种情况下,编译器会自动为你添加一个字段,并包装属性。它基本上相当于做:

private string forename;
public string Forename
{
    get
    { 
        return this.forename;
    }
    set
    {
        this.forename = value;
    }
}

使用属性而不是字段有很多优点。即使您不需要某些特定原因(例如数据绑定),这也有助于您的 API 面向未来。

主要问题是,如果您创建一个字段,但在您的应用程序的 v2 中,需要一个属性,您将破坏 API。通过预先使用自动属性,您可以随时更改您的 API,而无需担心源代码或二进制兼容性问题。

于 2009-08-18T15:37:39.000 回答
6

这意味着您希望稍后添加逻辑。

如果您这样做并从一开始就将其作为属性,您将不必重新构建依赖代码。如果您将其从变量更改为属性,那么您将不得不这样做。

于 2009-08-18T15:34:00.740 回答
4

考虑查看一些关于自动属性和公共字段之间的区别字段与属性自动属性 ​​- 有用与否的相关主题。,为什么不使用公共字段

于 2009-08-18T15:45:45.553 回答
2

公共数据成员是邪恶的(因为对象不控制对其自身状态的修改 - 它成为全局变量)。打破封装——OOP 的一个原则。

自动属性可以提供封装并避免为简单属性编写样板代码的苦差事。

public string ID { get; set;}

您可以在将来将自动属性更改为非自动属性(例如,您在 setter 中有一些验证)......并且不会破坏现有客户端。

string m_ID;
public string ID
{
   get { return m_ID; }
   set 
   { 
     //validate value conforms to a certain pattern via a regex match
     m_ID = value;
   }
}

您不能对公共数据属性做同样的事情。将数据属性更改为属性将强制现有客户端重新编译,然后才能再次交互。

于 2009-08-18T15:35:58.350 回答
1

一方面,您可以将属性设置为虚拟并在继承类中实现逻辑。之后您还可以在同一个类中实现逻辑,并且不会对依赖于该类的任何代码产生副作用。

于 2009-08-18T15:33:50.943 回答
1

添加自动属性时,编译器会将 get set 逻辑添加到应用程序中,这意味着如果您稍后添加此逻辑,并且从外部库对您的属性的引用仍然有效。

如果您从公共变量迁移到属性,这对于引用您的其他库来说将是一个重大更改 - 因此,为什么不从自动属性开始呢?:)

于 2009-08-18T15:39:29.187 回答
1

并非所有属性都需要获取/设置逻辑。如果他们这样做,您将使用私有变量。例如,在 MV-something 模式中,您的模型将没有太多逻辑。但您可以根据需要混合搭配。

如果您要使用建议的字段代替属性,例如,您不能定义一个接口来正确描述您的类,因为接口不能包含数据字段。

于 2009-08-18T16:05:06.123 回答
1

属性就像合同,您可以更改属性的实现而不影响使用您的类和属性的客户端。您今天可能没有任何逻辑,但是随着业务需求的变化以及如果您想引入任何代码,属性是您最安全的选择。以下 2 个链接是优秀的 c# 视频教程。第一个视频解释了仅使用字段而不是属性的需要,第二个视频解释了不同类型的属性。我发现它们非常有用。

需要 C# 中的属性

C# 中的属性、只读、只写、读/写、自动实现

于 2012-06-26T11:36:15.747 回答
0

看看下面的代码和解释。
The most common implementation for a property is getter or a setter that simply reads and writes to a private field of the same type as a property. An automatic property declaration instructs the compiler to provide this implementation. The compiler automatically generates a private backing field.
查看以下代码:-

    public class Stock 
    {
      decimal currentPrice ;  // private backing field.
      public decimal CurrentPrice 
      {
        get { return currentPrice ; }
        set { currentPrice = value ; }
      }
   }

相同的代码可以重写为:-

   public class Stock
   {
     public decimal CurrentPrice { get ; set ; } // The compiler will auto generate a backing field.
   }

来源:- 简而言之 C#

于 2013-12-10T12:21:29.880 回答