使用属性公开类似数组的数据结构

时间:2009-03-13 09:22:31

标签: c# data-structures properties

通常将内部数据结构公开为业务类的属性。但是当我们必须暴露类似数组的结构(如List< Rule>规则)时,我们可能会遇到错误使用的问题(如选项1中所示)。

它建议将这种数据结构的克隆暴露为属性,这样内部结构就不会受到干扰。

对于这个,有没有人有一个很好的解决方案?

public class Rule 
{
}

public class RulesManager 
{
    List<Rule> rules = new List<Rule>();

    public List<Rule> Rules
    {
        get { return rules; }
        set { rules = value; }
    }

    public void Add(Rule r)
    {
        rules.Add(r);
        // Do something else after add;
    }

    public void Delete(Rule r) 
    {
        rules.Remove(r);
        // Do something else after delete;
    }
}
public class CallingCode 
{
    public static void Main() 
    {
        RulesManager r = new RulesManager();
        // Option 1            
        r.Rules.Add(new Rule());
        // Option 2 
        r.Add(new Rule());
    }
}

5 个答案:

答案 0 :(得分:2)

您可以使用Clone返回rules的只读版本,而不是返回rules.AsReadOnly()

public IList<Rule> Rules
{
  get { return rules.AsReadOnly(); }
// set { rules = value; -- should not be allowed to set if read only!
}

请注意IList

答案 1 :(得分:0)

您可以返回IEnumerable,而不是返回List。 IEnumerable允许用户遍历集合,但它不允许用户轻松修改它。

或者你可以返回一个arryay而不是一个列表。这将创建用户无法轻易修改的列表副本。

最后,您应该知道用户也可能修改集合的内容。这可能是您想要的,但您可能还想要退回商品的副本。

答案 2 :(得分:0)

我认为将IList公开为属性是很常见的,但我更喜欢只公开显式的Add / Delete函数。如果你正在开发更多的框架,你也可以考虑在你的类中实现一个集合接口(例如IList)。

而不是:

public List<Rule> Rules
{
    get { return rules; }
    set { rules = value; }
}

我更喜欢在类上实现IEnumerable<T>和索引器,以便我可以控制列表中发生的事情。

答案 3 :(得分:0)

查看ReadOnlyCollectionAsReadOnly()列表方法。

答案 4 :(得分:0)

一个基本的解决方法是使用List<T>.AsReadOnly()方法,它将围绕ReadOnlyCollection包装列表以阻止任何“写入”访问。当然,你必须将setter设为私有,否则就没有意义......

另一种选择是实现您自己的IList,它会在“写入”访问的情况下提醒您,并允许您执行业务逻辑。