Chr*_*ins 23 .net c# performance coding-style
我正在阅读MSDN上有关do的一些文档,而不是关于某些内容是作为属性还是作为方法实现的.我特别遇到一个规则,我有一个问题.
如果"操作返回数组"使用方法(而不是属性).
页面在这里:在属性和方法之间进行选择
使用操作返回数组的方法,因为要保留内部数组,您必须返回数组的深层副本,而不是对属性使用的数组的引用.这一事实,加上开发人员使用属性就好像是字段一样,可能会导致代码效率非常低下.
我知道属性的get方法会返回对数组的引用,这样即使没有set也可以更改数组.在他们提供的示例中,每次访问属性时,他们都会对数组进行深层复制,我想这是为了避免发生这种情况的可能性,而这反过来效率非常低.
如果属性刚刚返回引用并且没有完成所有复制,那么效率不高,对吧?并且使用方法而不是属性不会自动保护列表不被修改.这几乎是相同的情况,你仍然需要一个深层复制.
使用属性只是返回对数组的引用总是不好的做法?如果您希望调用者能够修改数组,或者您不关心它们是否修改它,该怎么办?它仍然是坏的,为什么,如果是这样,什么是允许调用者修改的正确方法?
Jam*_*are 10
你能让调用者通过属性修改内部数组吗?是的,当然,但你会遇到一系列可能的问题.你如何处理这些问题以及你可以忍受的事情取决于你.
从严格意义上讲,MSDN建议是正确的.那说我已经看过List<T>并且T[]在课前返回了属性.如果你的类是一个非常简单的POCO,这不是一个大问题,因为那些类只是原始数据而且没有真正的业务逻辑可以影响.
也就是说,如果我返回一个列表,并且我不希望任何人弄乱内部列表,我每次都要返回一个深层拷贝,或者一个ReadOnlyCollection或者一个迭代器.例如,我有很多地方缓存Web服务请求调用,当我返回缓存项时,我不希望调用者修改该数据,或者他们将修改我正在缓存的内容.因此,我制作了深层副本(仍然比Web服务调用的开销更快).
您只需知道您的使用是否需要安全.该课程仅供内部消费吗?或者它是否被更广泛的受众消费,你不知道他们将用它做什么?这些类型的问题可能会推动您的回复.
抱歉,这取决于"取决于"答案,但它确实取决于您的目标是什么,以及该类的内部是否对变化敏感.
更新 你也可以返回一个迭代器,我会避免将IEnumerable作为超类up-cast返回,因为它可以被强制转换,但是如果你返回一个迭代器(比如使用Skip(0))你是安全的(除了当然能够修改包含的对象).
例如:
public IEnumerable<T> SomeList
{
get { return _internalList.Skip(0); }
}
Run Code Online (Sandbox Code Playgroud)
比以下更好:
public IEnumerable<T> SomeList
{
get { return _internalList; }
}
Run Code Online (Sandbox Code Playgroud)
因为后者仍然可以被转换回List<T>或者它是什么,而第一个是迭代器而且不能被修改.