2008-09-17 58 views
3

我有一个字符串属性的类,实际上是用分隔符连接的几个字符串。“代理属性”是不错的风格?

我想知道,如果是好的形式有代理性质是这样的:

public string ActualProperty 
{ 
    get { return actualProperty; } 
    set { actualProperty = value; } 
} 

public string[] IndividualStrings 
{ 
    get { return ActualProperty.Split(.....); } 
    set 
    { 
      // join strings from array in propval .... ; 
      ActualProperty = propval; 
    } 
} 

有我忽略任何风险?

回答

0

那么我会说你的“设置”是高风险的,如果有人不知道他们必须通过一个已经加入的值序列,或者你上面的例子可能没有这样做。如果字符串已经包含分隔符 - 你会中断。

根据这个属性的使用频率,我确定性能不是很好。

1

定义“好”。它不应该中断(除非你没有妥善保证传递给Split()的分隔符绝不允许在单独的字符串本身中),但是如果IndividualStrings的访问频率比ActualProperty更频繁,那么你最终会更频繁地解析actualProperty比你应该。当然,如果反过来是真的,那么你做得很好......如果两者都经常被调用,以致任何不必要的解析或连接都是不可接受的,那么只需存储两者并在该值改变时重新解析。

0

我不确定这个设计的好处是什么。我认为这种拆分在扩展方法中会更好。至少,我会移除IndividualStrings属性上的setter,或将其移入两个方法:string [] SplitActualProperty()和void MergeToActualProperty(string [] parts)。

2

将两个可设置的属性链接在一起在我看来是不好的juju。切换到显式的get/set方法而不是属性,如果这真的是你想要的。代码具有非明显的副作用,几乎总是会在以后出现。尽可能保持简单和直接的事情。另外,如果你有一个属性是一个包含子字符串的格式化字符串,它看起来像你真正想要的是一个单独的结构/类的属性,而不是滥用原始类型。

2

看起来数组是真实的数据,而单字符的东西是一个方便。这很好,但我想说的是诸如序列化和成员克隆这样的东西,它们将获取和设置两个可写属性。

我想我会;

  • 保持阵列作为属性
  • 提供GetJoinedString(string seperator)方法。
  • 提供了一种SetStrings(string joined, string seperator)Parse(string joined, string seperator)方法。

实际上,字符串中的分隔符不是类的一部分,而是一个短暂的细节。明确引用它,例如,一个CSV应用程序可以传递一个逗号,其中制表符分隔的应用程序可以传递一个制表符。它会让您的应用更易于维护。此外,它消除了为相同的实际数据设置两个getter和setter的令人讨厌的问题。

1

属性意图是一类非常简单的成员;获取或设置属性的值应该被认为是微不足道的操作没有显著的副作用

如果设置属性会导致比分配财产的其他更改类的公共价值观,这比一个基本的分配更加显著,并可能不再是一个非常适合的属性。

“复杂”的属性是危险的,因为它是从呼叫者的预期打破。属性被解释为字段(带有副作用),但作为字段您希望能够分配一个值,然后稍后检索该值。通过这种方式,调用者应该能够分配给多个属性并在稍后再次检索它们的值。

在你的榜样,我不能一个值分配给两个属性检索它们;一个值会影响另一个值。这打破了财产的基本期望。如果您创建一个方法将值同时分配给两个属性,并使这两个属性都是只读的,则更容易了解设置值的位置。

另外,顺便说一句:

它通常被认为是不好的做法,从属性返回临时数组。数组可能是不可变的,但它们的内容不是。这意味着你可以改变数组中的一个值,这个值将会继续与对象一起存在。

例如:

YourClass i = new YourClass(); 
i.IndividualStrings[0] = "Hello temporary array!"; 

这段代码看起来像它在IndividualStrings特性改变的值,但实际上该阵列由属性创建,而不是在任何地方分配的,所以阵列和变化将下降立即超出范围。

public string ActualProperty { get; set; } 

public string[] GetIndividualStrings() 
{ 
    return ActualProperty.Split(.....); 
} 

public void SetFromIndividualStrings(string[] values) 
{ 
    // join strings from array .... ; 
}