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


当前回答

传统上,私有字段是通过getter和setter方法设置的。为了减少代码,您可以使用财产来设置字段。

其他回答

当您希望您的私有变量(字段)可以被其他类中的类对象访问时,您需要为这些变量创建财产。

例如,如果我的变量名为“id”,而“name”是私有的但可能存在这样的情况,即类外部的读/写操作需要此变量。在这种情况下,属性可以帮助我根据为属性定义的get/set来读取/写入该变量。属性可以是readonly/writeonly/readwriteboth。

这是演示

class Employee
{
    // Private Fields for Employee
    private int id;
    private string name;

    //Property for id variable/field
    public int EmployeeId
    {
       get
       {
          return id;
       }
       set
       {
          id = value;
       }
    }

    //Property for name variable/field
    public string EmployeeName
    {
       get
       {
          return name;
       }
       set
       {
          name = value;
       }
   }
}

class MyMain
{
    public static void Main(string [] args)
    {
       Employee aEmployee = new Employee();
       aEmployee.EmployeeId = 101;
       aEmployee.EmployeeName = "Sundaran S";
    }
}

财产的主要优点是允许您更改对象上数据的访问方式,而不会破坏其公共接口。例如,如果您需要添加额外的验证,或者将存储的字段更改为计算字段,那么如果您最初将字段作为属性公开,则可以很容易地执行此操作。如果您只是直接公开了一个字段,那么您必须更改类的公共接口以添加新功能。这种改变会破坏现有的客户机,要求他们在使用新版本的代码之前重新编译。

如果您编写了一个为广泛使用而设计的类库(如数百万人使用的.NET Framework),这可能是一个问题。然而,如果您正在编写一个在小代码库内部使用的类(例如<=50K行),这真的不是什么大问题,因为没有人会受到您的更改的负面影响。在这种情况下,这真的只是个人喜好。

面向对象的编程原则表明,类的内部工作应该对外界隐藏。如果公开一个字段,本质上就是公开类的内部实现。因此,我们用财产(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
}

使用财产,您可以在属性值更改时(也称为PropertyChangedEvent)或在值更改为支持取消之前引发事件。

这对于(直接访问)字段是不可能的。

public class Person {
 private string _name;

 public event EventHandler NameChanging;     
 public event EventHandler NameChanged;

 public string Name{
  get
  {
     return _name;
  }
  set
  {
     OnNameChanging();
     _name = value;
     OnNameChanged();
  }
 }

 private void OnNameChanging(){       
     NameChanging?.Invoke(this,EventArgs.Empty);       
 }

 private void OnNameChanged(){
     NameChanged?.Invoke(this,EventArgs.Empty);
 }
}

传统上,私有字段是通过getter和setter方法设置的。为了减少代码,您可以使用财产来设置字段。