如何创建具有嵌套T's的泛型方法?
本文关键字:泛型方法 嵌套 何创建 创建 | 更新日期: 2023-09-27 17:49:24
我有一个通用的扩展方法
public static IList<T> Replace<T>(this IList<T> source, Ilist<T> newList) where T:IStateful
我叫它using
myStatefulSetOfStuff = myStatefulSetOfStuff.Replace(GetNewSetOfStuff());
但是,我意识到,我的方法将适用于所有实现ICollection的集合,所以我将其更改为
public static ICollection<T> Replace<T>(this ICollection<T> source, ICollection<T> newList) where T:IStateful
但是,现在该方法返回一个icolcollection,这迫使我将调用写成:
myStatefulSetOfStuff = myStatefulSetOfStuff.Replace(GetNewSetOfStuff()).ToList();
我如何重写我的方法,使我不需要.ToList()
在我的调用?
编辑:似乎有些混乱,所以我要设法弄清楚。我有一张单子。我想用一个新列表对那个列表执行一个操作。没有问题。我想出了如何用扩展方法返回List。
但是我意识到,嘿,Replace()中的实际代码并不是特定于列表的,它可以应用于任何集合。因此,我修改了Replace以返回一个iccollection。然后强制调用方法看起来像
var newStuff = left.Replace(right).ToList()
或
var newStuff = left.Replace(right).ToArray()
等。
但我不想说ToList, ToArray等,我希望方法只从源对象推断出正确的返回类型。所以我写入
var newStuff = left.Replace(right);
和newStuff的类型与left相同。右也是相同的类型
试试下面的
public static TCollection Replace<TCollection, TItem>(
this TCollection source,
TCollection newList)
where TCollection : ICollection<TItem>
where TItem : IStateful
下面是一个用例示例
interface IStateful { }
class Foo : IStateful { }
static void Test()
{
ICollection<Foo> left = null, right= null;
left.Replace<ICollection<Foo>, Foo>(right);
}
不幸的是,在这个场景中,泛型参数似乎是必要的(无法使类型推断适用于这个特定的场景)
编辑
我的回答是基于对问题的一点误读。我认为目的是将source
的类型流到方法的返回类型。在进一步重读后,虽然它似乎你想要流任何源,并在所有情况下返回一个List
。既然如此,我建议你看看里德的回答。 如果您需要它始终返回IList<T>,
,只需将其更改为:
public static IList<T> Replace<T>(this ICollection<T> source, ICollection<T> newList) where T:IStateful
并将.ToList()
调用放在扩展方法中(除非它已经在内部创建了一个列表)。
也就是说,如果您愿意的话,可以通过使用两个类型参数来"嵌套"它。