我做了这个扩展,我必须修改源列表上的属性值。我遇到的问题是它没有改变源列表中的值,项目的值改变得很好。
这是我的扩展:
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/