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


当前回答

想想看:你有一个房间和一扇门可以进入这个房间。如果你想检查谁是如何进来并保护你的房间的,那么你应该使用财产,否则他们不会是任何门,每个人都很容易进来,没有任何规定

class Room {
   public string sectionOne;
   public string sectionTwo;
}

Room r = new Room();
r.sectionOne = "enter";

人们很容易进入第一区,没有任何检查

class Room 
{
   private string sectionOne;
   private string sectionTwo;

   public string SectionOne 
   {
      get 
      {
        return sectionOne; 
      }
      set 
      { 
        sectionOne = Check(value); 
      }
   }
}

Room r = new Room();
r.SectionOne = "enter";

现在你检查了这个人,知道他是否有什么不好的地方

其他回答

财产显示字段。字段应该(几乎总是)对类保持私有,并通过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指出,您还可以在访问属性时执行其他逻辑,例如验证,这是另一个有用的功能。

基本区别和一般区别是:

领域

始终给予get和set访问权限不会造成副作用(引发异常、调用方法、更改字段(获取/设置的字段除外)等)

财产

并非总是同时提供get和set访问权限CAN导致副作用

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

(这真的应该是一条评论,但我不能发表评论,所以如果不适合作为帖子,请原谅)。

我曾经在一个地方工作,推荐的做法是使用公共字段而不是财产,而等效的属性def只访问字段,如:

get { return _afield; }
set { _afield = value; }

他们的理由是,如果需要的话,公共领域可以在未来晚些时候转化为财产。当时我觉得有点奇怪。从这些帖子来看,这里似乎也没有多少人会同意。你可能会说些什么来改变现状?

编辑:我应该补充一点,这里的所有代码库都是同时编译的,所以他们可能认为更改类的公共接口(通过将公共字段更改为属性)不是问题。

其他信息:默认情况下,get和set访问器与属性本身一样可访问。通过对访问器应用更严格的访问修饰符,可以分别控制/限制访问器的可访问性(对于get和set)。

例子:

public string Name
{
    get
    {
        return name;
    }
    protected set
    {
        name = value;
    }
}

这里get仍然是公共访问的(因为属性是公共的),但set是受保护的(一个更受限制的访问说明符)。