C# 使用get时更改对象状态

C# 使用get时更改对象状态,c#,class,C#,Class,嗨,当我在微软的网站上读到这篇文章的时候,有人能解释一下为什么这是一个糟糕的编程,因为我认为它可以用更少的代码行做更多的事情。Ps我在课堂上还是个新手 使用get访问器更改对象的状态是一种糟糕的编程风格。例如,每次访问数字字段时,下列访问器都会产生更改对象状态的副作用。 private int number; public int Number { get { return number++; // Don't do this } } 当然 Get被

嗨,当我在微软的网站上读到这篇文章的时候,有人能解释一下为什么这是一个糟糕的编程,因为我认为它可以用更少的代码行做更多的事情。Ps我在课堂上还是个新手

使用get访问器更改对象的状态是一种糟糕的编程风格。例如,每次访问数字字段时,下列访问器都会产生更改对象状态的副作用。

private int number;
public int Number
{
    get
    {
        return number++;   // Don't do this
    }
}
当然


Get被大多数开发人员作为只读操作读取,阅读代码的人不会期望Get属性修改任何数据。这是一个惯例,但当你考虑它时,它是有意义的——它帮助我们大家理解彼此的代码

在您引用的示例中,一种方法是将其分为两个调用-一个get,后跟一个set以递增变量。。。另一种方法是实现一种方法来增加变量并返回结果。

当然


Get被大多数开发人员作为只读操作读取,阅读代码的人不会期望Get属性修改任何数据。这是一个惯例,但当你考虑它时,它是有意义的——它帮助我们大家理解彼此的代码


在您引用的示例中,一种方法是将其分为两个调用-一个get,后跟一个set以递增变量。。。另一种方法是实现一种方法来增加变量并返回结果。

如示例所示,让我们假设一种情况。
您正在开发一个API,在该API中,您提供了限制用户使用的集合大小(编号),但允许用户查看集合中有多少内容/项目。
现在,一个人必须在三个不同的地方得到计数——在这种情况下,每次他得到计数时,你都在增加计数,这是绝对错误的

希望您能理解这一点,为什么它是一种糟糕的编程风格。

如您的示例所示,让我们假设一种情况。
您正在开发一个API,在该API中,您提供了限制用户使用的集合大小(编号),但允许用户查看集合中有多少内容/项目。
现在,一个人必须在三个不同的地方得到计数——在这种情况下,每次他得到计数时,你都在增加计数,这是绝对错误的

希望您能理解这一点,为什么它是一种糟糕的编程风格。

在get访问器上修改对象的状态有完全合理的理由,这就是为什么允许它(例如,出于统计目的):

例如:

private int _timesMyCustomerWasAccessed;
private Customer _myCustomer;
public Customer MyCustomer
{
  get
  {
    _timesMyCustomerWasAccessed++;
    return _myCustomer;
  }
}
这就是说,对对象进行状态更改通常是不好的做法,这会影响从外部观察该对象的方式(如果更改应用于相同属性的结果,则情况更糟)

这是一个语法问题:get访问器不应该有副作用,因为它们看起来很奇怪,并且使代码很难理解

在您的示例代码中。设想以下代码访问该属性:

Console.Write(String.Format("{0} {1} {2},
          myObject.Number, 
          myObject.Number, 
          myObject.Number));
产出将是:

0 1 2
如果您尝试阅读该代码,除非对象的副作用有完整的文档记录,否则是什么让您认为
myObject.Number
每次都会给出不同的结果

对于您的特殊情况,如果您有一个方法,它将更有意义:

public int GetNumberAndIncrease()
{
  return number++;
}
当你阅读代码时:

Console.Write(String.Format("{0} {1} {2},
          myObject.GetNumberAndIncrease(), 
          myObject.GetNumberAndIncrease(), 
          myObject.GetNumberAndIncrease()));

只要读取代码,输出就完全可以理解。在get访问器上修改对象的状态是完全有理由的,这就是为什么允许这样做(例如,出于统计目的):

例如:

private int _timesMyCustomerWasAccessed;
private Customer _myCustomer;
public Customer MyCustomer
{
  get
  {
    _timesMyCustomerWasAccessed++;
    return _myCustomer;
  }
}
这就是说,对对象进行状态更改通常是不好的做法,这会影响从外部观察该对象的方式(如果更改应用于相同属性的结果,则情况更糟)

这是一个语法问题:get访问器不应该有副作用,因为它们看起来很奇怪,并且使代码很难理解

在您的示例代码中。设想以下代码访问该属性:

Console.Write(String.Format("{0} {1} {2},
          myObject.Number, 
          myObject.Number, 
          myObject.Number));
产出将是:

0 1 2
如果您尝试阅读该代码,除非对象的副作用有完整的文档记录,否则是什么让您认为
myObject.Number
每次都会给出不同的结果

对于您的特殊情况,如果您有一个方法,它将更有意义:

public int GetNumberAndIncrease()
{
  return number++;
}
当你阅读代码时:

Console.Write(String.Format("{0} {1} {2},
          myObject.GetNumberAndIncrease(), 
          myObject.GetNumberAndIncrease(), 
          myObject.GetNumberAndIncrease()));

只需阅读该代码即可完全理解输出

“阅读您的代码的人不会期望Get属性修改任何数据”-唯一的例外(但是,外部世界通常看不到)返回的是第一次检索时延迟初始化的状态。@O.R.Mapper我不会确切地调用延迟加载更改状态,因为第一次访问时,它仍然会向调用方检索值。他没有意识到这个手术是懒惰的。@YuvalItzchakov:因此我声明它通常是外部世界看不见的。非常感谢,我现在完全理解了!“阅读您的代码的人不会期望Get属性修改任何数据”-唯一的例外(通常是外部世界看不见的)是第一次检索时延迟初始化的返回。@O.R.Mapper我不会确切地称为延迟加载更改状态,因为当第一次访问时,它仍然会向调用者检索值。他没有意识到这个手术是懒惰的。@YuvalItzchakov:因此我声明它通常是外部世界看不见的。非常感谢,我现在完全理解了!将其更改为方法。您的示例类似于类
System.Random
,它有一个方法(不是属性)
Next
,该方法返回伪随机序列中的下一个数字。请更改它