这是什么类型的财产?有必要吗?

时间:2010-01-13 14:57:04

标签: c# nhibernate

创建映射时,我正在读取您的集合属性应如下所示:

  public virtual ReadOnlyCollection<Product> Products
  {
           get { return new ReadOnlyCollection<Product>(new List<Product>(_products).AsReadOnly()); }
  }

为什么必须这样?它似乎每次被引用时都会返回一个新的集合?

7 个答案:

答案 0 :(得分:7)

它返回一个包装类实例,阻止调用者直接修改你要返回的集合。

如果您只是简单地返回基础列表,任何调用者都可以以可能破坏实际拥有列表的类的方式更改它。

即使您将列表作为只读接口(例如IEnumerable或ICollection)返回,也不会阻止调用者执行运行时转换并进入列表。

通过返回包装器对象,可以防止来自的调用者能够更改列表。包装器不公开任何允许更改基础列表的方法,并且尝试转换包装器对象将失败。包装器不会复制数据 - 它只是保留对列表的引用,并阻止写操作。

在ORM映射的情况下,这允许对象模型控制在哪个访问点可以改变对象之间的关系。

答案 1 :(得分:4)

你的代码看起来有点奇怪。首先它创建一个_products的副本,然后它使它只读,然后再将它包装在ReadOnlyCollection中!

如果要公开应该是只读的集合,请执行以下操作:

private List<Product> _products = new List<Product>();

private ReadOnlyCollection<Product> _readonlyProducts =
    new ReadOnlyCollection(_products);

public ReadOnlyCollection<Product> Products
{
    get
    {
        return _readonlyProducts;
    }
}

每次都不需要重新创建ReadOnlyCollection(或复制或复制或复制集合)。

答案 2 :(得分:2)

您的馆藏不 始终只读。这取决于列表的确切内容。如果它实际上只是一个引用列表,那么你甚至可以返回IEnumerable而不是ReadOnlyCollection,除非你明确需要一个只读集合。

为了使它成为一个只读集合,我会这样做:

private List<Product> products = new List<Product>();

public ReadOnlyCollection<Product> Products { get { return products.AsReadOnly(); } }

无需使用AsReadOnly语句包装new ReadOnlyCollection方法。或者你可以这样做:

public ReadOnlyCollection<Product> Products { get { return new ReadOnlyCollection<Product>(products); } }

但是,我只是打电话给AsReadOnly,因为我认为在内部它只是为你包装你的清单。

答案 3 :(得分:1)

我相信它建议像这样构建它,这样你就无法修改调用代码中的列表。通常你可以操作它(因为它将通过引用传递) - 添加项目,删除项目等。这确保你必须使用setter来更改内部列表。

我不会说 完全相同,除非你希望你的getter返回只读列表。

答案 4 :(得分:0)

它专门返回一个无法修改的新集合。虽然看起来有点傻。除非我弄错了,否则可能是:

public virtual ReadOnlyCollection<Product> Products
{
    get
    {
        return new List<Product>(_products).AsReadOnly();
    }
}

或者,如果_products已经某种List<Product>

public virtual ReadOnlyCollection<Product> Products
{
    get
    {
        return _products.AsReadOnly();
    }
}

答案 5 :(得分:0)

这段代码对我来说似乎是多余的......为什么不只是return _products.AsReadOnly()? (假设_products是List<T>,数组或任何公开AsReadOnly方法的类型)

答案 6 :(得分:0)

我认为_productsICollection<Product>IEnumerable<Product> - 在这种情况下,我认为只有new List<Product>(_products).AsReadOnly()就足够了。 如果_productsIList<Product>,那么new ReadOnlyCollection<Product>(_products)就足够了。 决定是否使用它取决于类的设计 - 在某些情况下,返回将每个Product隐藏到只读ProductView或ProductDTO实例中的集合适配器会更好。