c语言中<CR>是什么意思,关于c#:Collection< T>

本文讨论了代码审查中关于接口设计的建议,提倡使用`Collection`或接口代替`List`,以提高API的灵活性和未来扩展性。通过避免硬编码List,可以保持接口清晰,便于子类化和适应不同集合需求,同时减少消费者代码的复杂性。
摘要由CSDN通过智能技术生成

代码如下:

namespace Test

{

public interface IMyClass

{

List GetList();

}

public class MyClass : IMyClass

{

public List GetList()

{

return new List();

}

}

}

当我运行代码分析时,我得到了以下建议。

Warning 3 CA1002 : Microsoft.Design : Change 'List' in 'IMyClass.GetList()' to use Collection, ReadOnlyCollection or KeyedCollection

我应该如何解决这个问题?这里的好做法是什么?

为了回答问题的"为什么"部分,即为什么不使用List,原因是未来验证和API的简单性。

未来打样

List的设计不是为了通过对其子类化而易于扩展;它的设计是为了快速地进行内部实现。您会注意到它上的方法不是虚拟的,因此不能被重写,并且它的Add/Insert/Remove操作没有钩子。

这意味着,如果将来需要更改集合的行为(例如,拒绝人们试图添加的空对象,或者在发生这种情况时执行其他工作,例如更新类状态),则需要更改返回到可以子类的集合的类型,这将是一个中断的接口更改(C我们更改诸如不允许空值之类的东西的语义也可能是一个接口更改,但是像更新内部类状态这样的事情是不允许的)。

因此,通过返回一个很容易被子类化的类(如Collection)或一个接口(如IList、ICollection或IEnumerable,您可以将内部实现更改为不同的集合类型以满足您的需要,而不必破坏消费者的代码,因为它仍然可以作为他们所期望的类型返回。叮叮声。

简单API

List包含了很多有用的操作,如BinarySearch和Sort等。但是,如果这是一个您要公开的集合,那么很可能您控制了列表的语义,而不是使用者。因此,虽然您的类在内部可能需要这些操作,但类的消费者不太可能(甚至应该)调用它们。

因此,通过提供一个更简单的集合类或接口,可以减少API用户看到的成员数量,并使其更易于使用。

这是一个死气沉沉的回应。另一篇关于这个主题的好文章可以在这里找到:blogs.msdn.com/fxcop/archive/2006/04/27/…

我明白你的第一点,但我不知道我是否同意你的API简单性部分。

stackoverflow.com/a/398988/2632991这也是一篇很好的文章,关于集合和列表之间的区别。

blogs.msdn.com/fxcop/archive/2006/04/27/…->已经死了。我们有新的信息吗?

工作链接:blogs.msdn.microsoft.com/kcwalina/2005/09/26/…

我将亲自声明它以返回接口而不是具体的集合。如果您真的想要访问列表,请使用IList。否则,考虑ICollection和IEnumerable。

然后IList会扩展ICollection接口吗?

是的,IList扩展了ICollection。我将添加文档链接。

@乔恩:我知道这很古老,但是你能在blogs.msdn.com/b/kcwalina/archive/2005/09/26/474010.aspx上评论一下Krzysztof的话吗?具体来说,他的评论,江户十一〔0〕CA1002似乎与Krzysztof的评论一致。我无法想象为什么要推荐一个具体的集合而不是一个接口,以及为什么要区分输入/输出。

@纳尔逊:很少有人要求呼叫者传递不可变的列表,但是返回一个列表是合理的,这样他们就知道它是绝对不可变的。但不确定其他收藏。如果有更多的细节就好了。

这不是针对具体案件的。显然,一般情况下,ReadOnlyCollection对于输入没有意义。同样地,作为输入,IList表示"我需要sort()或IList拥有的其他成员",这对于输出来说是没有意义的。但我的意思是,为什么推荐ICollection作为输入,Collection作为输出。为什么不按照您的建议使用ICollection作为输出?

@尼尔森:老实说,我不知道。最好能从Krzysztof那里得到更多的信息。

我认为这与不含糊有关。Collection和ReadOnlyCollection都来源于ICollection(即没有IReadOnlyCollection)。如果您返回接口,那么它是哪一个以及是否可以修改并不明显。不管怎样,谢谢你的意见。这对我来说是一张很好的健康支票。

还有一些需要补充的东西,尽管这已经很久没有被问到了。

当您的列表类型从List而不是Collection派生时,您不能实现Collection实现的受保护的虚拟方法。这意味着,如果对列表进行了任何修改,则派生类型将无法响应。这是因为List假设您在添加或删除项时知道。能够响应通知是一种开销,因此List不提供它。

在外部代码可以访问集合的情况下,您可能无法控制添加或删除项的时间。因此,Collection提供了一种方法来了解您的列表何时被修改。

在这种情况下,我通常尝试公开所需的最少数量的实现。如果消费者不需要知道您实际上正在使用列表,那么您就不需要返回列表。通过返回Microsoft建议的集合,您可以隐藏这样一个事实:您使用的是一个来自类消费者的列表,并将其与内部更改隔离开来。

它主要是抽象出您自己的实现,而不是将列表对象直接暴露出来进行操作。

让其他对象(或人)直接修改对象的状态是不好的做法。想想财产获得者/设定者。

采集->正常采集readOnlyCollection->用于不应修改的集合keyedcollection->当您需要字典时。

如何修复它取决于您希望类做什么以及getList()方法的用途。你能详细解释一下吗?

但是collection和keyedcollection也不是只读的。

@纳法尔,我怎么说的?

您声明不允许其他对象(或人)直接修改对象的状态并列出3种集合类型。除非以东十一〔十二〕二人不服从。

这是指"良好实践"。请提供适当的上下文。下面的列表简单地说明了这类类型的基本要求,因为OP想要了解警告。然后我继续问他关于以东的目的(13),以便能够更正确地帮助他。

我没有说过,使用这三种类型会立即让你进入"良好实践"的位置。

好吧,我明白这一点。但我认为推理部分仍然不健全。你说Collection有助于抽象内部实现,并防止直接操纵内部列表。怎样?Collection只是一个包装器,在传递的同一个实例上操作。它是一个动态集合,用于继承,而不是其他任何东西(Greg的答案在这里更相关)。

让我们在聊天中继续讨论。

我认为还没有人回答"为什么"这一部分…所以这里是。为什么"你"应该使用Collection而不是List,是因为如果你公开List,那么任何能够访问你的对象的人都可以修改列表中的项目。而Collection应该表示您正在创建自己的"添加"、"删除"等方法。

你可能不需要担心,因为你可能只是为自己(或者一些同事)编写接口。下面是另一个可能有意义的例子。

如果有公共数组,例如:

public int[] MyIntegers { get; }

您可能会认为,因为只有一个"get"访问器,没有人可以处理这些值,但这不是真的。任何人都可以这样改变里面的值:

someObject.MyIngegers[3] = 12345;

就我个人而言,大多数情况下我只使用List。但是如果你正在设计一个类库,你要把它交给随机的开发人员,你需要依赖于对象的状态…那么你就要自己制作收藏,并从那里锁定它:)

"如果将list返回到客户端代码,则当客户端代码修改集合时,将无法接收通知。"-fx cop…另请参阅"msdn.microsoft.com/en-us/library/0fss9skc.aspx"…哇,看来我还没下马呢:)

哇-几年后,我看到我贴在上面评论的链接末尾有一个引用,所以它不起作用…msdn.microsoft.com/en-us/library/0fss9skc.aspx

我看不出退货有什么问题

this.InternalData.Filter(crteria).ToList();

如果我返回一个断开连接的内部数据副本,或者一个数据查询的分离结果——我可以安全地返回List,而不暴露任何实现细节,并允许以方便的方式使用返回的数据。

但这取决于我所期望的消费者类型——如果这是类似于数据网格的东西,我宁愿返回IEnumerable,在大多数情况下,这将是项目的复制列表:)

集合类实际上只是围绕其他集合的包装类,用来隐藏它们的实现细节和其他特性。我认为这与面向对象语言中隐藏编码模式的属性有关。

我认为您不应该担心它,但是如果您真的想取悦代码分析工具,只需执行以下操作:

//using System.Collections.ObjectModel;

Collection myCollection = new Collection(myList);

由于一般不变性,这不起作用:(

对不起,那是个打字错误。i menat collection。我真的很期待能接触到C 4和一般协方差btw!

据我所知,用EDOCX1[4]包装既不保护自身也不保护底层集合。

这段代码是为了"取悦代码分析工具"。我不认为@tamasczinege在任何地方说使用Collection会立即保护您的基础收藏。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值