首页 / 知识

关于c#:“代理属性”是好的样式吗?

2023-04-16 20:13:00

关于c#:“代理属性”是好的样式吗?

Are “proxy properties” good style?

我有一个带有字符串属性的类,实际上是几个用分隔符连接的字符串。

我想知道具有这样的代理属性是否是一种好形式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
    }
}

我有忽略任何风险吗?


似乎数组是真实的数据,单字符串的东西很方便。很好,但是我想说要注意诸如序列化和成员克隆之类的事情,它们将获取并设置两个可写属性。

我想我会的。

  • 将数组保留为属性
  • 提供GetJoinedString(string seperator)方法。
  • 提供SetStrings(string joined, string seperator)Parse(string joined, string seperator)方法。

实际上,字符串中的分隔符实际上并不是类的一部分,而是短暂的细节。明确引用它,例如,CSV应用程序可以传递逗号,制表符分隔的应用程序可以传递标签。这将使您的应用程序易于维护。而且,它消除了为相同的实际数据使用两个getter和setter的麻烦问题。


在我看来,将两个可设置的属性链接在一起并不是一件好事。如果确实需要,请切换到使用显式的get / set方法而不是属性。具有明显作用的代码以后几乎总是会咬你。尽可能使事情简单明了。

另外,如果您有一个属性,该属性是包含子字符串的格式化字符串,那么您真正想要的是该属性的单独struct /类,而不是滥用原始类型。


属性旨在成为类的非常简单的成员。获取或设置属性的值应该被认为是微不足道的操作,没有明显的副作用。

如果设置属性导致除分配的属性以外的类的公共值发生更改,则这比基本分配更重要,并且可能不再适合该属性。

"复杂"属性很危险,因为它超出了呼叫者的期望。属性被解释为字段(具有副作用),但是您希望将其解释为可以分配值并随后检索该值的字段。这样,调用者应该期望能够分配给多个属性,并在以后再次检索它们的值。

在您的示例中,我无法为两个属性都赋值并检索它们;一个值会影响另一个。这打破了对该物业的基本期望。如果您创建了一种同时为这两个属性分配值并使两个属性都为只读的方法,则可以更轻松地了解在何处设置值。

另外,顺便说一句:

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

例如:

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

这段代码看起来像是在更改IndividualStrings属性中的值,但是实际上数组是由该属性创建的,并且没有分配任何位置,因此该数组和更改将立即超出范围。

1
2
3
4
5
6
7
8
9
10
11
public string ActualProperty { get; set; }

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

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

定义"好"。它不会中断(除非您未能正确保证传递给Split()的定界符永远不会在各个字符串中使用),但是如果IndividualStrings的访问频率比ActualProperty的访问频率高,您将结束最多解析ActualProperty的次数比您应有的要多。当然,如果相反是正确的,那么您就做得很好...并且如果经常调用两者,以至于任何不必要的解析或连接都不可接受,那么只需存储两者并在值更改时重新解析即可。


我不确定这种设计的好处是什么。我认为使用扩展方法可以更好地实现拆分。

至少,我将删除IndividualStrings属性上的设置器,或将其移入两个方法:string [] SplitActualProperty()和void MergeToActualProperty(string []部分)。


好吧,我想说您的"组合"是高风险的,如果有人不知道他们必须传递已经加入的值序列,或者上面的示例可能会遗漏该怎么办?如果字符串已经包含分隔符,该怎么办-您会中断。

我确信根据该属性的使用频率,性能不是很好。


属性代理字符串连接

最新内容

相关内容

猜你喜欢