Использование функции Linq Zip для объединения коллекций для просмотра в Silverlight - PullRequest
0 голосов
/ 24 сентября 2011

На основании предыдущего вопроса у меня было Здесь .Я хотел объединить две коллекции, чтобы объединенные данные могли затем отображаться в DataGrid пользовательского интерфейса Silverlight.

Используя функцию Linq Zip, я смог объединить две мои коллекции следующим образом:

public void CombineAllCollections()
    {
       var combineAll = Persons.Zip(PhoneNumbers, (x, y) => new
        {
            FirstName = x.FirstName,
            LastName = x.LastName,
            Address = x.Address,
            State = x.State,
            Zip = x.Zip,
            AreaCode = y.AreaCode,
            PhoneNumber = y.Number
        });
      }

Это, кажется, делает то, что я хотел.Однако вывод является анонимным типом.Как я могу привести комбинированный тип All в коллекцию (List, ObservableColl. IENum), которую затем можно передать в представление в моем пользовательском интерфейсе (Привязать к сетке данных).Затем выходные данные должны отображать в сетке столбец и значение для каждого элемента (как указано выше в семи столбцах).

Заранее спасибо

-Cheers

1 Ответ

4 голосов
/ 24 сентября 2011

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

Например:

public void CombineAllCollections()
{
   var combineAll = Persons.Zip(PhoneNumbers, (x, y) => new PersonWithPhoneNumber
    {
        FirstName = x.FirstName,
        LastName = x.LastName,
        Address = x.Address,
        State = x.State,
        Zip = x.Zip,
        AreaCode = y.AreaCode,
        PhoneNumber = y.Number
    });
 }

Где PersonWithPhoneNumber - это тип со всеми указанными свойствами.

Затем вы можете вызвать ToList () для результата, чтобы преобразовать его в IList<PersonWithPhoneNumber>, или вы можете оставить его в том виде, в котором он находится, как IEnumerable<PersonWithPhoneNumber>

EDIT

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

using System;
using System.Collections.Generic;
using System.Linq;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            var xs = new[] {1, 2, 3, 4, 5, 6};
            var ys = new[] {7, 8, 9, 10, 11, 12};

            var zipped = xs.Zip(ys, (x, y) =>
                                    new Dictionary<string, object>
                                        {
                                            { "X", x},
                                            { "Y", y}
                                        });

            foreach (var pair in zipped.SelectMany(tuple => tuple))
            {
                Console.WriteLine("{0} = {1}", pair.Key, pair.Value);
            }
        }
    }
}

Таким образом, вы можете иметь столько слов / значений в словаре для каждого элемента, сколько захотите. Однако при использовании этого метода вы, по сути, теряете безопасность типов и в конечном итоге будете упаковывать все типы значений для каждого свойства. Это означает, что вам нужно будет знать тип, на который вы хотите вернуться. Я бы честно не рекомендовал делать это. Я просто сделал бы тип, даже если этому типу нужно 100 свойств. В этом сценарии авто-свойства и хороший текстовый редактор - ваш лучший друг.

Вы также можете использовать новый динамический тип в C # 4 с платформой .NET 4.0, как в следующем примере:

using System;
using System.Dynamic;
using System.Linq;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            var xs = new[] {1, 2, 3, 4, 5, 6};
            var ys = new[] {7, 8, 9, 10, 11, 12};

            var zipped = xs.Zip(ys, (x, y) =>
                                        {
                                            dynamic value = new ExpandoObject();

                                            value.X = x;
                                            value.Y = y;

                                            return value;
                                        });

            foreach (var pair in zipped)
            {
                Console.WriteLine("X = {0}, Y = {1}", pair.X, pair.Y);
            }
        }
    }
}

Это привнесет динамику в ваш код. Который может не иметь желаемых показателей производительности и может привести к множеству ошибок во время выполнения, если вы не следите за тем, что делаете. Это связано с тем, что при создании или доступе к нему можно было неправильно ввести свойство (это также проблема с настройкой словаря), что приведет к исключению во время выполнения при попытке доступа к нему. Опять же, вероятно, лучше всего использовать бетон с именем напечатанным в конце.

...