Объедините данные, собранные из разных источников, в один объект IEnumberable - PullRequest
0 голосов
/ 03 октября 2019

У меня есть этот метод ниже, который собирает данные из разных источников и возвращает их как один IEnumerable.

У меня возникли проблемы, когда я выясняю, как объединить все источники в один объект типа TotalRoomContents.

TotalRoomContents имеет тип IEnumerable<String>.

Здесьнезавершенный метод:

    public static TotalRoomContents GetRoomContents(this Dungeon dungeon)
    {
        var customArmor = dungeon.Rooms
                    .Select(pe => pe.Room)
                    .Where(e => e.Monster.IsActive);
            // check each customArmor object to see if it exists in the MapLookupByRoomId dictionary
            if (customArmor != null && MapLookupByRoomId.ContainsKey(customArmor.Id))
                // add all item(s) of type customArmor to TotalRoomContents()

            if(dungeon.RoomType?.InventoryContent != null)
            {
                    // add item(s) from dungeon.RoomType?.InventoryContent to TotalRoomContents()
            }

            return new TotalRoomContents()
    }

Как видите, я не знаю, как добавить элемент (ы) к объекту TotalRoomContents.

Элементы будут из dungeon.RoomType?.InventoryContent и все customArmor объекты, найденные в запросе linq.

Есть ли способ сделать это одним методом или мне нужно создать какой-то другой метод для этого?

Спасибо!

Ответы [ 2 ]

1 голос
/ 03 октября 2019

Почему бы вам не создать список "RoomContent" (который представляет собой то, что может содержать комната) и начать добавлять все результаты, отличные от других ваших запросов?

List<RoomContent> TotalRoomContents = new List<RoomContent>();
if (/* Whatever condition needs to be met */)
{
    TotalRoomContents.Add(/* Whatever you may want */);
}

Кроме того, вам следуетзнать, что запросы Linq не выполняются до тех пор, пока коду не потребуется его перечислить, поэтому, в принципе, вы можете построить запрос поэтапно:

// This is just to simulate the data source
IQueryable<RoomContent> query = allPossibleRoomContents.AsQueryable();

query = query.Where(x => x.ContentDescription = "Sword");
query = query.Where(x => x.ContentDescription = "Axe");

// This is where the actual work is done
return query.ToList();

Надеюсь, это поможет!

1 голос
/ 03 октября 2019

Вы можете создать класс-оболочку, который позаботится об этом. Возможная реализация может выглядеть так:

public class AggregateEnumerable<T> : IEnumerable<T> {
    private readonly IEnumerable<T>[] _sources;

    public AggregateEnumerable( params IEnumerable<T>[] sources ) {
        _sources = sources;
    }
    public IEnumerator<T> GetEnumerator() {
        foreach( var source in _sources ) {
            var enumerator = source.GetEnumerator();
            while( enumerator.MoveNext() )
                yield return enumerator.Current;
        }
    }

    IEnumerator IEnumerable.GetEnumerator() {
        return GetEnumerator();
    }
}

И тогда вы будете использовать ее как

var firstEnumerable = new[] { "Peter", "John" };
var secondEnumerable = new[] { "Thomas", "George" };
var myEnum = new AggregateEnumerable<string>(firstEnumerable, secondEnumerable);      

foreach( var value in myEnum )
    Console.WriteLine(value);
...