c# - 林克扩展。更改源列表中的属性值

标签 c# linq extension-methods

我做了这个扩展,我必须修改源列表上的属性值。我遇到的问题是它没有改变源列表中的值,项目的值改变得很好。

这是我的扩展:

public static IEnumerable<TSource> SetIndex<TSource, TResult>(
    this IEnumerable<TSource> source, 
    Expression<Func<TSource, TResult>> propertyExpression)
{
    MemberExpression body = propertyExpression.Body as MemberExpression;
    if (body == null)
    {
        return source;
    }

    PropertyInfo propertyInfo = body.Member as PropertyInfo;
    if (propertyInfo == null || propertyInfo.PropertyType != typeof(int))
    {
        return source;
    }

    string propertyName = body.Member.Name;
    int index = 0;
    foreach (TSource item in source)
    {
        propertyInfo.SetValue(item, index++, null);
    }

    return source;
}

这是我要测试的代码:

public class Persona
{
    public string Name { get; set; }

    public string Lastname { get; set; }
}

public class PersonaGroup
{
    public string Lastname { get; set; }

    public int Count { get; set; }

    public int Index { get; set; }
}


IList<Persona> listPersonas = new List<Persona>()
{
    new Persona{ Lastname = "Lopez", Name = "Tilo" },
    new Persona{ Lastname = "Dominguez", Name = "Raul" },
    new Persona{ Lastname = "Martinez", Name = "Manuel" },
    new Persona{ Lastname = "Martinez", Name = "Rogelio" },
    new Persona{ Lastname = "Lopez", Name = "Roberto" },
    new Persona{ Lastname = "Martinez", Name = "Alen" },
    new Persona{ Lastname = "Lopez", Name = "Mario" },
    new Persona{ Lastname = "Dominguez", Name = "Duran" },
    new Persona{ Lastname = "Martinez", Name = "Maria" },
    new Persona{ Lastname = "Dominguez", Name = "Marta" },
    new Persona{ Lastname = "Lopez", Name = "Pedro" },
    new Persona{ Lastname = "Dominguez", Name = "Martin" },
    new Persona{ Lastname = "Dominguez", Name = "Diego" },
    new Persona{ Lastname = "Lopez", Name = "El" }
};

IList<PersonaGroup> listPersonasGroups = listPersonas
                                .GroupBy(p => p.Lastname)
                                .Select(pg => new PersonaGroup { Lastname = pg.Key, Count = pg.Count() })
                                .SetIndex(pg => pg.Index)
                                .ToList();

foreach (PersonaGroup personaGroup in listPersonasGroups)
{
    Console.WriteLine("{0} - {1} : {2}", 
                personaGroup.Index, 
                personaGroup.Count, 
                personaGroup.Lastname);
}

Console.ReadKey();

结果:

0 - 5 : Lopez
0 - 5 : Dominguez
0 - 4 : Martinez

当我写下我的问题时,我发现问题出在使用 Select 时,但我不知道如何解决它或为什么我无法修改列表。 我知道我可以在 foreach 中使用 yield return item; 但更改“source”会更有用。

谢谢。

最佳答案

您可以使用标准 LINQ 方法做您想做的事:

IList<PersonaGroup> listPersonasGroups = listPersonas
                                .GroupBy(p => p.Lastname)
                                .Select((pg, i) => new PersonaGroup {
                                                        Lastname = pg.Key,
                                                        Count = pg.Count(),
                                                        Index = i
                                })
                                .ToList();

Select重载 Func<TSource, int, TResult>参数的工作方式类似于您的自定义扩展方法:

public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    if (selector == null)
    {
        throw Error.ArgumentNull("selector");
    }
    return Enumerable.SelectIterator<TSource, TResult>(source, selector);
}

private static IEnumerable<TResult> SelectIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
{
    int num = -1;
    checked
    {
        foreach (TSource current in source)
        {
            num++;
            yield return selector(current, num);
        }
        yield break;
    }
}

关于c# - 林克扩展。更改源列表中的属性值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18659771/

相关文章:

c# - 使用扩展方法的字符串和日期时间实用程序函数库的建议

c# - 如何在运行时替换 HTML 的占位符值并使用 iTextSharp 生成 PDF?

c# - "".All(char.IsNumber) 返回 True

c# - 声明空字节 - 可空对象必须有一个值?

c# - htmlAttributes 未与我的扩展中的标签生成器合并

c# - 将对象转换为 List<T> 以便能够使用扩展方法

c# - Facebook 在不打开 WebBrowser 的情况下注销 Windows Phone 应用程序

c# - 使用 check C# 合并两个数据表

c# - 如何将 appsettings.json 文件添加到我的 Azure Function 3.0 配置中?

c# - 比较 C# 中的 Sum 方法