ICollection <t>上的扩展方法不会更改调用列表?

时间:2017-09-25 19:32:29

标签: c# generics extension-methods icollection

我想创建一个在List上运行并接受另一个列表的扩展方法:

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)

2 个答案:

答案 0 :(得分:0)

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

您想要将源列表的内容复制到目标中,但是您首先要替换目标列表以确保它是空的?如果您还要替换目标列表,为什么不简单地替换它?

target = source.ToList();

另外,您如何建议实施&#34;在t&#34;上做一些工作?在一般的扩展方法中,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 :(得分:-1)

如果您按值传递列表,则无法将新实例分配给targetList。您可以添加,删除或修改现有列表的内容,但如果要分配其他实例,则需要添加ref关键字以允许分配。