让我们假设我们有这个功能:
List<string> ToCollectionString<T>(List<T> collectinon);
现在我们如何更改List
以返回与给定参数相同的特定IEnumerable
?我们得到List
因此返回List
,我们得到Stack
,所以返回Stack
等。
如果我们有:
List<T> ToCollectionString<T>(List<T>);
它将是
K ToCollectionString<K,T>(K collection) where K:IEnumerable<T>
但是,如果我们有List<string>
?
答案 0 :(得分:1)
假设您正在尝试创建传入但保留字符串的相同集合类型的实例。
一般情况下这是不可能的,因为传入的类型可能无法根据您拥有的信息构造类型的新实例(显而易见的情况 - list.Select(...)
作为参数传递的结果 - 类型实现它不有可见的构造函数)。
在极少数情况下,当你可以构造类型时,你必须使用反射来找到确切的参数类型Using C# reflection to call a constructor。如果你需要空集合 - 你就完成了。
如果您需要将项目添加到生成的集合中(即您希望在每个源项目上调用#34; ToString&#34;)如果您需要查找带有IEnumerable
的克隆构造作为参数好运,否则你必须填充结果集合(可能带有反射 - How to use reflection to add a new item to a collection)。如果您可以将传入类型限制为支持&#34的界面;添加项目&#34;功能(即IList
)至少第二部分可以强类型化。
注意:返回IEnumerable<string>
(即return collection.Select(x=>x.ToString())
并让调用者构造正确的类型可能更容易也更有用 - 这样可以避免所有反射复杂性并让调用者使用强类型值而不是转换结果。它还可以避免在调用者对其负责时无法构造类型的情况:
var stronglyTyped = new Stack(ToCollectionString(collectinon));