我有一个类,我将其称为SpiderNest
,它具有类型List<Spider>
的属性,其中Spider
是一种具有属性的对象类型输入int
;我们将此属性称为NumberOfLegs
。我想要SpiderNest
类的方法或属性来获得我巢中所有蜘蛛的腿数总和。
是否首选使用这样的属性(原谅不良对象命名):
class SpiderNest {
// Our example property.
public List<Spider> Spiders { get; set; }
public int TotalLegNumber
{
get { return Spiders.Sum(spider => spider.NumberOfLegs); }
}
或方法?
class SpiderNest {
public List<Spider> Spiders { get; set; }
public int GetTotalNumberOfLegs()
{
return Spiders.Sum(spider => spider.NumberOfLegs);
}
}
你为什么选择这种方式?我知道这个问题可能很棘手,但每当我提出两种做事方式时,每种做事方式通常都会带来好处。谢谢!
答案 0 :(得分:5)
该方法没有副作用,但如果Spiders
很大,则计算费用可能很高。如果Spiders
很大,那么它应该是一个方法,否则将其作为属性。
答案 1 :(得分:1)
在MSDN上查看Choosing Between Properties and Methods
属性意味着像字段一样使用,这意味着属性不应该在计算上复杂或产生副作用。
使用方法,而不是属性[if] ......操作比字段集[或]更慢几个数量级......操作具有显着且可观察到的副作用。
让我们考虑一个例子 - 如果您的List
是从具有延迟加载的数据库中填充的,那么当您调用列表时,它会从数据库中填充 - 这意味着当您询问时对于您可能正在等待填充信息的总腿数 - 这不是即时操作。在这种情况下,最好使用方法。
另外,我总是感觉说GetXXX()
暗示该方法可以在执行中的不同点返回不同的值,而属性感觉就像它应该是更多静态数字。在此基础上,如果您计划在启动后向您的巢中添加蜘蛛,我将向GetXXX()
犯错。
答案 2 :(得分:0)
另一个暗示是它会产生副作用(比如改变另一个属性或某个内部状态)。如果是的话,即使它很便宜,也要把它变成一种方法。
在您的具体情况下,我会将其作为财产。如果计算可能需要很长时间(由于列表constains int.MaxValue
项目),我将在属性本身内创建一个缓存,它将在第一次调用此列值时或在列表已被调用时计算此值自上次计算以来发生了变化。或者可以在每次列表更改时的总和之前预先计算,并且在您的属性中,您只需返回最新的计算值。但所有这些可能性取决于列表元素的设计(例如它们是不可变的还是实现INotifyPropertyChanged?)以及列表更改的频率与客户端需要的总和的频率。