1

この拡張機能を作成しました。ソース リストのプロパティの値を変更する必要があります。私が抱えている問題は、ソースリストの値が変更されず、アイテムの値がうまく変更されることです。

これは私の拡張子です:

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わかりましたが、それを修正する方法や、リストを変更できない理由がわかりません。で使用できることはわかっていますyield return item;が、foreach「ソース」を変更する方が便利です。

ありがとう。

4

2 に答える 2

1

The problem is with this piece of code:

foreach (TSource item in source)
{
    propertyInfo.SetValue(item, index++, null);
}
return source;

source is deferred IEnumerable, which you enumerate twice. In return source; there are no changes at all. For instance you can change it to:

var array = source.ToArray();
foreach (TSource item in array)
{
    propertyInfo.SetValue(item, index++, null);
}
return array;
于 2013-09-06T14:14:19.923 に答える