何时在c#中使用get;set;?

32

我不明白初始化变量和这样获取其值之间的区别:

 //define a local variable.
   int i;

   i= 0;
   Console.WriteLine(i);

还有get;set;的用法:

public int i
{
   get;
   set;
}

i = 0;
Console.WriteLine(i);

我已经阅读了一些文章,但不理解何时应该使用它。


我认为在 public int i 后面不应该有括号。 - Ben Voigt
正如Hans的链接所提到的,这可能是最好的资源:http://csharpindepth.com/Articles/Chapter8/PropertiesMatter.aspx - Kirk Woll
1
@Hans:那个似乎没有涉及自动属性。不是重复。 - Ben Voigt
9个回答

26

基本上,在这种情况下,使用属性的(许多)优点之一是能够像这样向您的属性添加事件

  public delegate void ChangedEventHandler(object sender, EventArgs e);

  int m_i = 0;
  public int i 
  {
      get { return m_i; }
      set { m_i = value; iChanged(self, null); }
  }

  public ChangedEventHandler iChanged;

这允许代码知道何时更改了I的值(可能会有一些语法错误,我有一段时间没有专注于C#,但思路类似)。在winforms中,这非常重要,因为这是主要的方式来知道按钮(或类似物品)何时被点击。


此外,这还允许在属性的setter中添加额外功能,例如检查是否在特定范围内,如下所示:

  int m_i = 0;
  public int i {

  get { return m_i; }
  set { if (value > 10) throw new Exception("I cannot be greater than 10!"); m_i = value; }
  }

17
如果您认为可能需要更复杂的getter或setter,自动属性语法可以让您升级而无需重新编译所有调用者。但是,从字段(成员变量)移动到属性是一种破坏性的更改。 Eric Lippert讨论了这个主题。两次。

这才是真正的改变...其他答案都只是解释了什么是自动属性,而没有回答问题。 - Tomer W
你能详细说明从字段到属性的转变是如何破坏性的变化吗?我很难理解 { get; set; } 的原因,也看不出任何真正的理由。 - synek317

12

基本上,它添加了额外的负担以换取附加事件的能力。除此之外,它增加了复杂性和冗长度,使代码更难读懂。如果您需要添加验证处理程序,它是一种不错的方法。在某些情况下。在大多数情况下,您知道(也希望知道)变量(成员)被修改的确切位置。如果您不知道,则存在代码管理问题,而不是语言问题。

认为所有“面向对象”的东西都更好的想法是错误的。大多数开发人员都逐渐明白这一点。我已经从事这项工作30年了,我可以告诉您,有98次中有98次-简单就是更好。花费编码精力在不添加不必要复杂性的高效算法上,您将走得更远并且经受住趋势的考验。


11

先不要考虑属性…你真正需要问的问题(你可能甚至不知道)是为什么首先需要属性(或其他语言中的getter和setter)?

这是为了促进封装

属性只是提供了更好的语法,用于访问器,即getter和setter(实际上,属性在幕后包装了set()和get()方法)。

在C# 3中,C#团队推出了自动属性,因为绝大多数属性不会对变量执行任何操作(没有额外的逻辑),所以自动属性是这种情况的简写形式。


1
这是真正的答案。 - Celsiuss

8
您正在描述的语法称为自动属性。
在.NET 2.0引入此语法之前,我们创建属性的方式如下:
int _myVar;
int MyVar
{
    get { return _myVar; }
    set { _myVar = value; }
}

.NET 2.0引入了简写语法,允许编译器自动创建后备变量(_myVar是上述示例中的后备变量)

int MyVar
{
    get;
    set;
}

变量和属性之间的关键区别在于我们可以控制属性的获取和设置(例如只读属性或每次将值设置为属性时调用函数)。

2
public int i {get ; set;}

创建类型为 int 的自动属性 i

这是 int 类型的缩写

private int _i;
public int i
{
     get{ return _i;}
     set{ _i = i}
} 

2
让我感到困惑的部分是术语“accessor”、“mutator”和“property”,以及“{ get; set; }”,好像这是一种神奇的改进别名,而不仅仅是将字段设为“public”的简单操作。
  • accessor = 访问私有字段的方法(在C#中,是getter/setter)
  • mutator = 修改私有字段的方法(仅为setter)
  • property = 在C#中与accessor相同。

纯粹地说:

private int myNumber;
public int MyNumber { get; set; }

它们完全没用,只是噪声代码版本的一种。
public int myNumber;

如果你添加了以下这些检查:
private int myNumber;
public int MyNumber
{
    get
    {
        return myNumber;
    }
    set
    {
        if (myNumber < 0)
            throw new ArgumentOutOfRangeException;
        myNumber = value;
    }
}

然后它们实际上会提供常规的用于获取/设置的作用。

0

这基本上是面向对象编程的概念。

当你使用int i;(这被视为字段,该字段可以在内部使用,也可以根据访问修饰符从当前类外部使用。(公共,私有,受保护)

现在当您使用get; set;时,它是类的属性。它也可以从其他类设置,但不同之处在于它像方法一样访问,并提供其他功能,例如通知属性更改等。

如果您不想对其进行任何控制,则使用filed,但如果要进行控制,则使用property。此外,您可以使用public,private和protected来获取和设置,这也可以在封装方面提供更多灵活性。


0

这是面向对象编程的一个概念。

使用 Get\Set 属性有两个主要优点:

  1. 使用 get 和 set 方法,我们可以在派生类中更改变量值而不影响基类值。

例如:

class User
{

    private string name = "Suresh Dasari";
    public string Name
    {
     get
        {
            return name.ToUpper();

        }

        set
        {
       if (value == "Suresh")
             name = value;
       }
        }
    }

此外,在值设置属性部分,我们还可以验证、限制和触发事件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接