【发布时间】:2012-11-13 10:16:30
【问题描述】:
在为 API 编写通用扩展方法时,我在选择集合的返回类型时处于两难境地。我已经阅读了关于返回什么集合类型以及应该是什么设计选择的讨论。我一般更喜欢接受最基本的类型作为参数,并返回最丰富的类型。
我现在正在考虑返回与提供的相同类型。无论这是否是一个好的选择,有没有一种方法可以以易于使用的方式完成?
例如。让我有这个:
public static IEnumerable<T> Generize<T>(this IEnumerable<T> source)
where T : new()
{
var lst = source.ToList();
lst.Add(new T());
return lst.AsEnumerable(); //since return type is IEnumerable.
}
现在我想返回 IEnumerable、ICollection 或 IList,具体取决于参数 source。所以我稍微修改了一下。
public static S Generize<S, T>(this S source) where S : IEnumerable<T>
where T : new()
{
var lst = source.ToList();
lst.Add(new T());
return (S)lst.AsEnumerable(); //not sure if this works
}
我面临的主要问题是我无法调用函数Generize。
var d = new List<int> { 23, 23 };
d.Generize(); //can not find definition and no extension method by the name.....
d.Generize<List<int>, int>(); //works but so ugly..
正如 Marc 指出的那样,强制转换并非在任何地方都有效。如果
S无论如何是IEnumerable<T>,是否有更好的方法从List<T>返回S类型的集合?是否可以在不指定类型的情况下自动推断类型?
还有为什么
d.Generize()给出definition not found错误而不是types cannot be inferred错误?
编辑:
虽然IEnumberable<T> 可以是任何具体类型,但在我的情况下,它只会是T[] 或List<T> 之类的常见类型,或者来自Linq namsespace 的更多类型。处理它们都不容易。只是指出原来的问题现在对我来说没有意义。谢谢大家..!
【问题讨论】:
-
“工作但如此丑陋”只是偶然的工作;如果您使用数组或
Collection<T>尝试它,则会出错 -
@MarcGravell 让我看看。谢谢。
-
@MarcGravell 我不明白你。我尝试使用
int[]和ICollection<T>并且它有效.. -
如果
S是int[],你会得到“无法投射类型为 'System.Collections.Generic.List1[System.Int32]' to type 'System.Int32[]'.". IfS` 的对象是Collection<int>,你会得到”无法投射'System.Collections.Generic.List1[System.Int32]' to type 'System.Collections.ObjectModel.Collection1[System.Int32]' 类型的对象。”。基本上,你用“不确定这是否有效”标记的代码:不。 -
嗯,我意识到我的问题部分是愚蠢的,因为
IEnumerable<T>可以是任何风格,包括自定义类型。我将尝试自己发布一个处理反思的答案,只是为了回答。
标签: c# generics extension-methods ienumerable type-inference