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


当前回答

如果要使用线程原语,则必须使用字段。财产可以破坏线程代码。除此之外,科里所说的是正确的。

其他回答

财产用于显示字段。它们使用访问器(set、get),通过这些访问器可以读取、写入或操作私有字段的值。

财产不指定存储位置。相反,它们具有读取、写入或计算其值的访问器。

使用财产,我们可以对字段上设置的数据类型进行验证。

例如,我们有一个私有整数字段age,我们应该允许正值,因为age不能为负值。

我们可以使用getter和setter以及使用property两种方式来实现这一点。

 Using Getter and Setter

    // field
    private int _age;

    // setter
    public void set(int age){
      if (age <=0)
       throw new Exception();

      this._age = age;
    }

    // getter
    public int get (){
      return this._age;
    }

 Now using property we can do the same thing. In the value is a key word

    private int _age;

    public int Age{
    get{
        return this._age;
    }

    set{
       if (value <= 0)
         throw new Exception()
       }
    }

如果我们在get和set访问器中没有逻辑,我们可以使用自动实现的属性。

当使用自动实现的属性编译时,将创建一个只能通过get和set访问器访问的私有匿名字段。

public int Age{get;set;}

抽象财产抽象类可以具有抽象属性,该属性应在派生类中实现

public abstract class Person
   {
      public abstract string Name
      {
         get;
         set;
      }
      public abstract int Age
      {
         get;
         set;
      }
   }

// overriden something like this
// Declare a Name property of type string:
  public override string Name
  {
     get
     {
        return name;
     }
     set
     {
        name = value;
     }
  }

我们可以私下设置房产在这种情况下,我们可以私下设置auto属性(在类中设置)

public int MyProperty
{
    get; private set;
}

您可以使用此代码实现相同的效果。在该属性集中,由于我们必须直接将值设置为字段,因此功能不可用。

private int myProperty;
public int MyProperty
{
    get { return myProperty; }
}

财产是一种特殊的类成员。在财产中,我们使用预定义的Set或Get方法。它们使用访问器,通过访问器我们可以读取、写入或更改私有字段的值。

例如,让我们使用一个名为Employee的类,其中包含name、age和Employee_Id的私有字段。我们无法从类外部访问这些字段,但可以通过财产访问这些私有字段。

我们为什么使用财产?

公开类字段并公开它是有风险的,因为您无法控制分配和返回的内容。

为了通过示例清楚地理解这一点,让我们以一个具有ID、密码和姓名的学生班级为例。现在在这个例子中,公共领域的一些问题

ID不应为-ve。名称不能设置为空合格标记应为只读。如果缺少学生姓名,则不应返回姓名。

为了解决这个问题,我们使用Get和set方法。

// A simple example
public class student
{
    public int ID;
    public int passmark;
    public string name;
}

public class Program
{
    public static void Main(string[] args)
    {
       student s1 = new student();
       s1.ID = -101; // here ID can't be -ve
       s1.Name = null ; // here Name can't be null
    }
}

现在我们以get和set方法为例

public class student
{
    private int _ID;
    private int _passmark;
    private string_name ;
    // for id property
    public void SetID(int ID)
    {
        if(ID<=0)
        {
            throw new exception("student ID should be greater then 0");
        }
        this._ID = ID;
    }
    public int getID()
    {
        return_ID;
    }
}
public class programme
{
    public static void main()
    {
        student s1 = new student ();
        s1.SetID(101);
    }
    // Like this we also can use for Name property
    public void SetName(string Name)
    {
        if(string.IsNullOrEmpty(Name))
        {
            throw new exeception("name can not be null");
        }
        this._Name = Name;
    }
    public string GetName()
    {
        if( string.IsNullOrEmpty(This.Name))
        {
            return "No Name";
        }
        else
        {
            return this._name;
        }
    }
        // Like this we also can use for Passmark property
    public int Getpassmark()
    {
        return this._passmark;
    }
}

此外,财产允许您在设置值时使用逻辑。

因此,如果值大于x,您可以说只想将值设置为整数字段,否则将引发异常。

非常有用的功能。

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

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

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

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

例如数学PI

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