Вернуть анонимный тип из функции - PullRequest
20 голосов
/ 21 сентября 2011

Могу ли я использовать анонимный тип в качестве возвращаемого типа в функции, а затем заполнить возвращаемое значение массивом или какой-либо коллекцией, добавив при этом дополнительное поле в новый массив / коллекцию? извините за мой псевдокод ...

private var GetRowGroups(string columnName)
{
var groupQuery = from table in _dataSetDataTable.AsEnumerable()
                             group table by new { column1 = table[columnName] }
                                 into groupedTable
                                 select new
                                 {
                                     groupName = groupedTable.Key.column1,
                                     rowSpan = groupedTable.Count()
                                 };
    return groupQuery;

}

private void CreateListofRowGroups()
{
    var RowGroupList = new List<????>();
    RowGroupList.Add(GetRowGroups("col1"));
    RowGroupList.Add(GetRowGroups("col2"));
    RowGroupList.Add(GetRowGroups("col3"));

}

Ответы [ 6 ]

16 голосов
/ 21 сентября 2011

Нет, вы не можете вернуть анонимный тип из метода.Для получения дополнительной информации прочитайте этот MSDN документ.Используйте class или struct вместо типа anonymous.

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

Есливы используете Framework 4.0, тогда вы можете вернуть List<dynamic>, но будьте осторожны, чтобы получить доступ к свойствам анонимного объекта.

private List<dynamic> GetRowGroups(string columnName)
{
var groupQuery = from table in _dataSetDataTable.AsEnumerable()
                             group table by new { column1 = table[columnName] }
                                 into groupedTable
                                 select new
                                 {
                                     groupName = groupedTable.Key.column1,
                                     rowSpan = groupedTable.Count()
                                 };
    return groupQuery.ToList<dynamic>();
}
14 голосов
/ 21 сентября 2011

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

  1. Создайте простой тип для представления возвращаемого значения. (См. здесь и здесь ). Сделайте это просто путем генерации из использования .
  2. Создайте вспомогательный метод для приведения к анонимному типу , используя образец экземпляра для приведения.
4 голосов
/ 21 сентября 2011

Нет, вы не можете вернуть анонимный тип напрямую, но вы можете вернуть его, используя импровизированный интерфейс .Как то так:

public interface IMyInterface
{
    string GroupName { get;  }
    int RowSpan { get; }
}

private IEnumerable<IMyInterface> GetRowGroups()
{
    var list =
        from item in table
        select new
        {
            GroupName = groupedTable.Key.column1,
            RowSpan = groupedTable.Count()
        }
        .ActLike<IMyInterface>();

    return list;
}
2 голосов
/ 27 февраля 2013

Просто используйте и ArrayList

    public static ArrayList GetMembersItems(string ProjectGuid)
    {
        ArrayList items = new ArrayList(); 

              items.AddRange(yourVariable 
                        .Where(p => p.yourproperty == something)
                        .ToList());
            return items;
    }
1 голос
/ 21 сентября 2011

Используйте object, а не var. Вы должны будете использовать отражение, чтобы получить доступ к свойствам вне области анонимного типа.

т.е.

private object GetRowGroups(string columnName) 
...
var RowGroupList = new List<object>();
...
0 голосов
/ 21 декабря 2018

Из C # 7 вы можете вернуть список кортежей:

private IEnumerable<(string, string)> GetRowGroups(string columnName)
{
    return from table in _dataSetDataTable.AsEnumerable()
           group table by new { column1 = table[columnName] }
           into groupedTable
           select (groupedTable.Key.column1, groupedTable.Count());
}

Вы можете даже дать членам имена кортежей:

private IEnumerable<(string groupName, string rowSpan)> GetRowGroups(string columnName)
{
    return from table in _dataSetDataTable.AsEnumerable()
           group table by new { column1 = table[columnName] }
           into groupedTable
           select (groupedTable.Key.column1, groupedTable.Count());
}

Однако вам нужно System.ValueTuple из диспетчера пакетов Nuget.

В любом случае я предлагаю дать вещам четкое имя, которое включает их назначение, в частности, когда это является частью общедоступного API.Сказав это, вы должны создать класс, содержащий эти свойства, и вернуть список этого типа.

...