繁体   English   中英

使用IEnumerable <T> 输入方法参数

[英]Using IEnumerable<T> type in parameter of method

以前我使用IEnumerable<T>类型,如果我传递集合作为方法的参数。

但是最近,我遇到了以类似方式创建的IEnumerable<T>类型集合的问题:

var peoples = names.Select(name => new People(name));

在这种情况下,总是,如果我使用集合人(例如,foreach),它会创建类People的新实例,并且很容易导致错误。

所以我想问一下使用IEnumerable <T>类型参数是否正确。 我认为这可能会导致问题(参见上面的示例),不应使用此类型。 你推荐什么替代品( ICollection<T>IList<T>等)以及何时使用哪种替代品?

或者你认为这是一个愚蠢的问题,因为在Select方法中创建对象只使用傻瓜?

当然,我知道我可以使用ToArray()ToList()解决问题。 但是使用这种方法的其他人,却无法知道。 我想知道如何通过选择正确的类型参数来防止这种情况。 当我想要“枚举”对象时,列表或数组对我来说太具体了。

IEnumerable不是一个集合。 这只是你可以“枚举”的东西。 问题是没有将IEnumerable传递给您的方法,问题是如果您使用LINQ( Select方法),每次读取可枚举时它将再次执行代码。 如果您只想执行一次,可以使用ToArray()ToList()方法:

var peoples = names.Select(name => new People(name)).ToList();

像这样你仍然可以将它传递给任何接受IEnumerable (或List )的方法,它只会为每个人创建一个实例。

编辑:您的方法不应该担心这些问题。 这是来电者的问题。 使用可枚举而不是列表调用您的方法可能有充分的理由。 调用者应该知道,如果将枚举传递给不同的方法,则枚举会给出不同的结果,因此您不必担心。

唯一的例外是如果在方法本身中多次枚举参数。 在这种情况下,您应该将参数缓存在方法内的列表中,然后根据需要多次枚举列表。

ToArrayToList建议暴露的内容超出了人们最初的想法。 我们很想把这个建议简单地说是在调用站点调用ToList / ToArray或者你方法中的第一件事来纠正这个问题,但你的问题是IEnumerable<T>是否合适 - 你可以改变从IEnumerable<T>到其他东西的参数类型(如ICollection<T> ),它将调用者的onus转换为实现此接口的东西(注意T[]List<T>IList<T>Collection<T>都做)。 这种方法的部分问题是这些接口代表可变集合,而IEnumerable<T>宣告该方法枚举项目 - 这只是我不喜欢这种方法的原因之一。

如果潜在的错误根本不是一个错误怎么办? 也许调用者打算将这些作为防御性副本或哑数据对象 - 在后一种情况下,某些措施可能效率低下,但需要他们制作副本 - 但在这个提议的使用中它绝对不是一个错误。 同样,一个大小适合所有推荐都不适合,因为IEnumerable<T>对象不必永远终止 - 但要求传入的数组类型意味着无限(即计算)或仅仅大IEnumerable<T>对象是不可能的。

无论如何,我认为你提出有关防御性编程的问题是正确的。 但是,在这种情况下,我认为最好的解决方案是坚持使用IEnumerable<T>并根据他们可能在某些有限的情况下引入错误的猜测来教育而不是限制你的调用者。

解释一句话:

设计以防止白痴问题的问题是,白痴是如此天真。

希望这可以帮助。 干杯!

暂无
暂无

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

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