在C#中,是什么使字段与属性不同?何时应该使用字段而不是属性?


当前回答

字段是类的普通成员变量或成员实例。财产是获取和设置其值的抽象。财产也称为访问器,因为如果您将类中的字段公开为私有字段,则它们提供了更改和检索字段的方法。通常,您应该将成员变量声明为私有的,然后为它们声明或定义财产。

  class SomeClass
  {
     int numbera; //Field

     //Property 
    public static int numbera { get; set;}

  }

其他回答

字段是类中的变量。字段是可以通过使用访问修饰符封装的数据。

财产与字段类似,它们定义与对象关联的状态和数据。

与字段不同,属性有一种特殊的语法来控制用户如何读取数据和写入数据,这些被称为get和set运算符。集合逻辑通常可用于进行验证。

财产显示字段。字段应该(几乎总是)对类保持私有,并通过get和set财产进行访问。财产提供了一个抽象级别,允许您更改字段,同时不影响使用类的事物访问字段的外部方式。

public class MyClass
{
    // this is a field.  It is private to your class and stores the actual data.
    private string _myField;

    // this is a property. When accessed it uses the underlying field,
    // but only exposes the contract, which will not be affected by the underlying field
    public string MyProperty
    {
        get
        {
            return _myField;
        }
        set
        {
            _myField = value;
        }
    }

    // This is an AutoProperty (C# 3.0 and higher) - which is a shorthand syntax
    // used to generate a private field for you
    public int AnotherProperty { get; set; } 
}

@Kent指出,财产不需要封装字段,它们可以对其他字段进行计算,也可以用于其他目的。

@GSS指出,您还可以在访问属性时执行其他逻辑,例如验证,这是另一个有用的功能。

在大多数情况下,它将是您访问的属性名,而不是变量名(字段)。原因是,在.NET中,尤其是在C#中,它被认为是保护类中的每一条数据的良好做法,无论是实例变量还是静态变量(类变量),因为它与类相关联。

使用相应的财产保护所有这些变量,这些属性允许您定义、设置和获取访问器,并在操作这些数据片段时执行验证等操作。

但在其他情况下,如Math类(System命名空间),类中内置了一些静态财产。其中一个是数学常数PI

例如数学PI

因为PI是一块定义良好的数据,我们不需要有多个PI副本,它总是相同的值。因此,静态变量有时用于在类的对象之间共享数据,但也通常用于只需要一个数据副本的常量信息。

在后台,属性被编译为方法。因此,Name属性被编译为get_Name()和set_Name(字符串值)。如果您研究编译的代码,您可以看到这一点。因此,在使用它们时会有(非常)小的性能开销。通常,如果向外部公开字段,则始终使用Property,如果需要验证值,则通常在内部使用Property。

面向对象的编程原则表明,类的内部工作应该对外界隐藏。如果公开一个字段,本质上就是公开类的内部实现。因此,我们用财产(Properties)(或Java中的方法)包装字段,使我们能够在不破坏代码的情况下更改实现。考虑到我们可以在Property中放置逻辑,还允许我们在需要时执行验证逻辑等。C#有一个可能令人困惑的自动属性概念。这允许我们简单地定义Property,而C#编译器将为我们生成私有字段。

public class Person
{
   private string _name;

   public string Name
   {
      get
      {
         return _name;
      }
      set
      {
         _name = value;
      }
   }
   public int Age{get;set;} //AutoProperty generates private field for us
}