“将项目插入列表中的列表

时间:2015-07-29 12:52:55

标签: c# linq list

在阅读了List类一段时间后,我无法找到解决此问题的任何补救措施,我需要将值插入到主列表中保存的列表项中。

类Person的List,在其中保存另一个名为Blocks的列表,Blocks是一个int Lost of Blocks地址,供以后在工具中使用。

我尝试使用类List的insert方法将“block”的值插入List Blocks,如下所示:

_person.Insert(stuff, _person.Select(x => x.Blocks.Add(block)));

其中是一个包含要插入的值的int。 和 stuff 是IndexOf

找到的块的int索引

但是这引发了一个标记在Select子句下面的错误,其中包含

的描述
  

“错误8方法的类型参数   “System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerable,   System.Func)'无法从用法中推断出来。尝试   指定类型参数   明确。 C:\ Users \ User \ documents \ visual studio   2010 \ Projects \ NOOP \ NOOP_Tools \ DLC.cs 112 39 NOOP_Tools“

据我了解错误是在select语句中,但我不知道我哪里出错..

PS,我无法评论其中一个回复,由于我的低声誉而对我所面临的问题有一个接近的答案,这促使我寻找其他答案但却无处可去,因此,我不得不向确保我知道我做错了什么。

提前致谢

EDIT1

 public Action<Person, int> InsertBlockAction = (Class, block) => Class.Blocks.Add(block);

 public Action<Person, string> InserDataAction = (Class, data) => Class.Data = data;

我认为这可能就是答案。仍然需要测试它。

EDIT2 上述操作仅适用于List

中的每个var项

3 个答案:

答案 0 :(得分:2)

问题在于:

_person.Select(x => x.Blocks.Add(block))

Select需要一个返回值的函数 - 您只是因为一些未知原因而调用Add。由于Add不返回值,因此它不是有效的投影。

答案 1 :(得分:1)

如果你想操纵列表中的特定项目,你需要先以某种方式选择它,所以:

var personToEdit = _person[stuff]; // You said 'stuff' is your index

personToEdit.Blocks.Add(block);

答案 2 :(得分:0)

正如其他人所指出的那样,Select期望在执行投影时生成一个值。

根据我的理解,您真正想要的是一种简单的方法,可以根据项目列表添加内部列表。

我想出了以下扩展类:

public static class Extensions
{
    public static void AddNested<TOuter, TInner>(
        this IEnumerable<TOuter> outerItems,
        Func<TOuter, ICollection<TInner>> innerCollectionSelector,
        Func<TOuter, bool> outerPredicate,
        Func<TOuter, TInner> innerProducer
    )
    {
        foreach(var outer in outerItems)
        {
            innerCollectionSelector(outer).Add(innerProducer(outer));
        }
    }

    public static void AddNested<TOuter, TInner>(
        this IEnumerable<TOuter> outerItems,
        Func<TOuter, ICollection<TInner>> innerCollectionSelector,
        Func<TOuter, bool> outerPredicate,
        TInner innerItemToAdd
    )
    {
        outerItems.AddNested(innerCollectionSelector, outerPredicate, _ => innerItemToAdd);
    }

    public static void AddNested<TOuter, TInner>(
        this IEnumerable<TOuter> outerItems,
        Func<TOuter, ICollection<TInner>> innerCollectionSelector,
        TOuter outerItem,
        Func<TOuter, TInner> innerProducer
    )
    {
        outerItems.AddNested(innerCollectionSelector, i => i.Equals(outerItem), innerProducer);
    }

    public static void AddNested<TOuter, TInner>(
        this IEnumerable<TOuter> outerItems,
        Func<TOuter, ICollection<TInner>> innerCollectionSelector,
        TOuter outerItem,
        TInner innerItemToAdd
    )
    {
        outerItems.AddNested(innerCollectionSelector, outerItem, _ => innerItemToAdd);
    }
}

坚持使用您的人员和阻止列表,您可以执行以下操作:

public void DoSomething()
{
    // Add a new block for everyone called Bob
    people.AddNested(p => p.Blocks, p => p.FirstName == "Bob", p => new Block("Block For Bob"));

    // Add a new block for Bob Mackey
    people.AddNested(p => p.Blocks, p => p.FirstName == "Bob" && p.Surname == "Mackey", 
        p => new Block());

    // Add for specific item
    var person = people.Single(p => p.Surname == "dfsdfdfsdf");
    var block = CreateBlockForPerson(person);
    people.NestedAdd(p => p.Blocks, person, block);
}
  

注意:我的示例中的最后一个方案仅在people实际包含person的情况下有效,它只是默默地无法将block添加到{ {1}}。