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


当前回答

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

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

其他回答

我对一个字段的设计是,一个字段只需要由它的父级修改,也就是类修改。结果变量变为私有,然后为了能够赋予读取外部类/方法的权限,我只使用Get来遍历属性系统。然后,该字段由属性检索,并且是只读的!如果你想修改它,你必须通过方法(例如构造函数),我发现由于这种方法使你安全,我们可以更好地控制代码,因为我们“法兰”。我们可以很好地将所有的事情都公开,所以每个可能的情况,变量/方法/类等的概念。。。在我看来,这只是对代码开发和维护的一种帮助。例如,如果一个人使用公共字段恢复代码,那么他可以做任何事情,因此可以做与目标相关的“不合逻辑”的事情,即代码编写的逻辑。这是我的观点。

当我使用经典模型私有字段/公共只读财产时,对于10个私有字段,我应该编写10个公共财产!代码可以更快地变大。我发现了私有setter,现在我只对私有setter使用公共财产。setter在后台创建一个私有字段。

这就是为什么我以前的经典编程风格是:

public class MyClass
{
 private int _id;
 public int ID { get { return _id; } }
 public MyClass(int id)
 {
  _id = id;
 }
}

我的新编程风格:

public class MyClass
{
 public int ID { get; private set; }
 public MyClass(int id)
 {
  ID = id;
 }
}

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

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";

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

财产是一种特殊的类成员。在财产中,我们使用预定义的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;
    }
}

这里清楚地解释了区别。然而,只是为了总结和强调:

字段封装在类内部以进行内部操作,而财产可用于将类公开给外部世界,以及共享链接中显示的其他内部操作。此外,如果您希望基于特定字段的值加载某些方法或用户控件,则属性将为您完成此操作:

例如:

您可以在asp.net页面中的用户控件下方运行,只需为aspx页面中控件的Id前缀赋值,如下所示:

useMeId.Id=5 ---call the property of user control "UseMe.ascx"

使用Me.ascx

<%@ Register Src=~/"UseMe.ascx" TagPrefix="uc" TagName="UseMe" %>
<uc:UseMe runat="Server" id="useMeId" />

UseMe.ascx.cs

private int currentId;

public int Id
   {
      get
      {
         return currentId;
      }
      set
      {
         currentId = value;
       LoadInitialData(currentId);
      }
   }
Private void LoadinitialData(int currentIdParam)
{
//your action

}

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

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

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

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

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