如何创建具有嵌套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相同。右也是相同的类型

如何创建具有嵌套T's的泛型方法?

试试下面的

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()调用放在扩展方法中(除非它已经在内部创建了一个列表)。

也就是说,如果您愿意的话,可以通过使用两个类型参数来"嵌套"它。