Могу ли я выразить это более кратко, используя анонимный тип? - PullRequest
0 голосов
/ 29 октября 2011
switch(ID)
{
    case "CustomReportsContainer":
        foreach (var report in SessionRepository.Instance.CustomReports.ToList())
        {
            var reportItem = new RadListBoxItem(report.Name, report.ID.ToString());
            if (!Items.Any(item => int.Equals(item.Value, reportItem.Value)))
            {
                Items.Add(reportItem);
            }
        }
        break;
    case "HistoricalReportsContainer":
        foreach (var report in SessionRepository.Instance.HistoricalReports.ToList())
        {
            var reportItem = new RadListBoxItem(report.Name, report.ID.ToString());
            if (!Items.Any(item => int.Equals(item.Value, reportItem.Value)))
            {
                Items.Add(reportItem);
            }
        }
        break;
}

HistoricalReports и CustomReports являются коллекциями разных типов, но меня интересуют одни и те же два свойства от каждого типа объекта.Я подумал, что смогу использовать LINQ's Select и создать список объектов с анонимным типом.

Хотя я не могу создать неявно типизированную переменную без ее назначения.И поскольку я нахожусь внутри области действия оператора Switch ... я не могу назначить переменную var внутри оператора switch, а затем переместить остальную часть кода за пределы оператора switch.

Как мне выразитьэтот код?Является ли текущая реализация «лучшей»?

Тьфу, близко.Могу ли я что-нибудь сделать с этим?Это через наш API, поэтому я не могу изменить глубже.

ReportServices.GetAllCustomReports().Select(report => new { report.Name, report.ID} ).ToList().ForEach(customReport => _customReports.Add(customReport));

Error   2   Argument 1: cannot convert from 'AnonymousType#1' to 'CableSolve.Web.Dashboard.IReport'

Ответы [ 3 ]

4 голосов
/ 29 октября 2011

CustomReport и HistoricalReport должны реализовывать интерфейс IReport, который содержит свойства Id и Name (как минимум).

switch(ID)
{
    case "CustomReportsContainer":
        AddReportItems(SessionRepository.Instance.CustomReports);
        break;
    case "HistoricalReportsContainer":
        AddReportItems(SessionRepository.Instance.HistoricalReports);
        break;
}

private void AddReportItems(IEnumerable<IReport> reports)
{
    foreach (var report in reports)
    {
        var reportItem = new RadListBoxItem(report.Name, report.ID.ToString());
        if (!Items.Any(item => int.Equals(item.Value, reportItem.Value)))
        {
            Items.Add(reportItem);
        }
    }
}

Редактировать

В ответ на ваши дополнительные вопросы, возможно ли для GetAllCustomReports вернуть тип, который реализует интерфейс IReport?Это избавит от необходимости проецирования на анонимный тип через Select(report => new { report.Name, report.ID} ) и решит оставшуюся проблему.

2 голосов
/ 29 октября 2011

Если элементы имеют общий интерфейс или базовый тип (или вы можете изменить их так, как они делают) - тогда вы сможете выразить запрос LINQ на основе этого типа.

Если нет, вы можете ввести их как dynamic, если вы находитесь на C # 4, поскольку они имеют одинаковые свойства.

0 голосов
/ 29 октября 2011

Если вы ищете те же два свойства и они имеют одинаковое имя, возможно, у вас есть хороший кандидат для небольшого интерфейса?

...