2017-09-25 64 views
-3

我想创建一个列表运行的扩展方法,并接受其他列表:但是ICollection的扩展方法<T>不会更改调用列表?

public static void Charge<T, S>(this ICollection<T> targetList, ICollection<S> sourceList) where T : class, new() 
     { 
      if (targetList == null || sourceList == null) 
       throw new NullReferenceException(); 
      targetList = new List<T>(); 
      foreach (var item in sourceList) 
      { 
       T t = new T(); 
       //do work on t 
       targetList.Add(t); 
      } 

     } 

当我这样称呼它:

var targetList = new List<Item>(); 
targetList.Charge(sourceList); 

targetList不会改变(项目数= 0)

+0

删除'targetList = new List ();' –

+0

你为什么要做'targetList = new List ();'? – rbm

+0

您没有返回目标列表,也没有将其作为参考处理。 – Trioj

回答

-1

如果您通过值传递列表,则不能将新实例分配给targetList。您可以添加,删除或修改现有列表的内容,但是如果您想分配另一个实例,则需要添加ref关键字以允许分配。

+3

你不能用'ref'标记'this'这个扩展方法的参数。 – PetSerAl

+0

我知道。但是,既然这两个都是集合,你可以交换参数'公共静态无效收回(这个ICollection sourceList,ref ICollection targetList)' – Michael

0

建议的方法对我没有意义。

您希望将源列表中的内容复制到目标,但你首先要更换目标列表以确保它是空的?如果你打算替换目标列表,为什么不简单替换它呢?

target = source.ToList(); 

而且,你打算如何落实“关于t做一些工作”在一般的扩展方法,其中的ST的类型是不知道?为什么不这样做的地道的事情,例如:

target = source.Select(s => Transform(s)).ToList(); 

这里,我们假设Transform能够创建并从源对象填充目标对象的方法。

或者,你可以避开首先清除旧的重新分配一个新的列表:

target.Clear(); 
target.AddRange(source.Select(s => Transform(s))); 

如果你真的希望有一个单一的调用,你可以简单地包裹或者替代以上,例如:

public static List<TTarget> ToList<TSource, TTarget>(
    this IEnumerable<TSource> source, 
    Func<TSource, TTarget> conversion) 
{ 
    if (source == null) 
     throw new ArgumentNullException(nameof(source)); 
    if (conversion == null) 
     throw new ArgumentNullException(nameof(conversion)); 

    return source.Select(conversion).ToList(); 
} 

用法:

target = source.ToList(s => Transform(s)); 
+1

Re:只是调用ToList():据我所知,问题是OP的源列表与目标列表不同。真的,国际海事组织,我不明白为什么整个代码不像var newThings = oldThings.Select(thing => ConvertOldThingToNewThing(thing)); – Trioj

+0

谢谢,我不知何故错过了这一点。 –

+0

不用担心。诚实地说,我花了比我想要的时间更长的时间,才意识到这实际上只是一个带有变换的奇怪设计的Select()调用。 – Trioj