简体   繁体   English

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

[英]What kind of property is this? is it necessary?

When creating a mapping, I am reading that your collection property should look like: 在创建映射时,我正在读取您的集合属性应如下所示:

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

Why does it have to be like this? 为什么它必须是这样的? it seems to be returning a new collection everytime it is referenced? 它似乎每次被引用时返回一个新的集合?

It's returning a wrapper class instance that prevents callers from being able to directly modify the collection you are returning. 它返回一个包装类实例 ,阻止调用者能够直接修改您要返回的集合。

If you were to simply return the underlying list, any caller would be able to alter it in ways that may break the class that actually owns the list. 如果您只是简单地返回基础列表,则任何调用者都可以以可能破坏实际拥有该列表的类的方式更改它。

Even if you returned your list as a read-only interface (say IEnumerable, or ICollection), nothing prevents a caller from performing a run-time cast, and getting at the list. 即使您将列表作为只读接口(例如IEnumerable或ICollection)返回,也不会阻止调用者执行运行时转换并进入列表。

By returning a wrapper object, you can prevent the caller from ever being able to alter the list. 通过返回的包装对象,可以防止来电以往任何时候都能够改变列表。 The wrapper does not expose any methods that allow the underlying list to be altered, and attempting to cast the wrapper object will fail. 包装器不公开任何允许更改基础列表的方法,并且尝试转换包装器对象将失败。 The wrapper does not duplicate the data - it merely keeps a reference to the list, and prevents write operations. 包装器不会复制数据 - 它只是保留对列表的引用,并阻止写入操作。

In the case of ORM mappings, this allows the object-model to control at which access point you can alter a relationship between objects. 在ORM映射的情况下,这允许对象模型控制在哪个访问点可以改变对象之间的关系。

Your code looks a bit odd. 你的代码看起来有点奇怪。 First it creates a copy of _products, then it makes it read only, and then it wraps it in a ReadOnlyCollection again! 首先它创建一个_products的副本,然后它使它只读,然后再将它包装在ReadOnlyCollection中!

If you want to expose a collection that should be read-only, do something like this: 如果要公开应该是只读的集合,请执行以下操作:

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

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

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

No need to recreate the ReadOnlyCollection each time (or copy or or double-wrap the collection). 无需每次都重新创建ReadOnlyCollection(或复制或重复包装集合)。

Your collections don't have to always be read only. 您的收藏不必总是为只读。 It depends on exactly what the list is for. 这取决于列表的确切内容。 If it is really just a list for referencing then you can even return IEnumerable rather than ReadOnlyCollection unless you explictly need a readonly collection. 如果它实际上只是一个引用列表,那么你甚至可以返回IEnumerable而不是ReadOnlyCollection除非你明确需要一个只读集合。

To make it a readonly collection I would do: 为了使它成为一个只读集合,我会这样做:

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

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

There is no need to wrap the AsReadOnly method with a new ReadOnlyCollection statement. 不需要使用new ReadOnlyCollection语句包装AsReadOnly方法。 Alternatively you could do: 或者你可以这样做:

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

However, I would just go with calling AsReadOnly as I think internally it will just be wrapping your list up for you anyway. 但是,我会选择调用AsReadOnly因为我认为在内部它只是为你包装你的列表。

I believe it is recommending to build it like this so you can't modify the list in the calling code. 我相信它建议像这样构建它,这样你就无法修改调用代码中的列表。 Normally you'd be able to manipulate it (since it's going to be pass-by-reference) -- add items, delete items, etc. This ensures you have to use the setter to change the internal list. 通常你可以操作它(因为它将通过引用传递) - 添加项目,删除项目等。这确保你必须使用setter来更改内部列表。

I wouldn't say it has to be like that at all, unless you want your getters to return read-only lists. 我不会说这必须是干这种事情,除非你想让你的getter方法返回只读列表。

It is specifically returning a new collection that cannot be modified. 它专门返回一个无法修改的新集合。 Seems a little goofy though. 虽然看起来有点傻。 Unless I'm mistaken, it could be: 除非我弄错了,否则可能是:

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

or, if _products is some sort of List<Product> already: 或者,如果_products已经是某种List<Product>

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

This code seems redundant to me... why not just return _products.AsReadOnly() ? 这段代码对我来说似乎是多余的...为什么不return _products.AsReadOnly() (assuming _products is a List<T> , array or any type that exposes an AsReadOnly method) (假设_products是List<T> ,数组或公开AsReadOnly方法的任何类型)

I suppose that _products is ICollection<Product> or IEnumerable<Product> - in this case I think it is enough to have new List<Product>(_products).AsReadOnly() . 我认为_productsICollection<Product>IEnumerable<Product> - 在这种情况下,我认为new List<Product>(_products).AsReadOnly()就足够了。 If _products is IList<Product> then new ReadOnlyCollection<Product>(_products) is enough. 如果_productsIList<Product>new ReadOnlyCollection<Product>(_products)就足够了。 The decision whether to use this depends on the design of the class - in some cases it is even better to return collection adapter that hides every Product into a read-only ProductView or ProductDTO instance. 决定是否使用它取决于类的设计 - 在某些情况下,返回将每个Product隐藏到只读ProductView或ProductDTO实例的集合适配器会更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM