从函数返回匿名类型

时间:2011-09-21 02:59:25

标签: c# linq generics collections

我可以在函数中使用匿名类型作为返回类型,然后将返回值的内容填充到某种数组或集合中,同时还向新数组/集合添加其他字段吗?请原谅我的伪代码...

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 个答案:

答案 0 :(得分:16)

不,无法从方法中返回匿名类型。有关详细信息,请阅读this MSDN doc。使用classstruct代替anonymous类型。

你应该阅读博文 - Horrible grotty hack: returning an anonymous type instance

如果您使用的是框架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>();
}

答案 1 :(得分:14)

这是very popular question。通常,由于需要强类型,因此无法返回匿名类型。但是有一些解决方法。

  1. 创建一个简单类型来表示返回值。 (参见herehere)。通过generating from usage简化。
  2. 使用示例实例为cast to the anonymous type创建一个帮助方法。

答案 2 :(得分:4)

不,您不能直接返回匿名类型,但可以使用impromptu interface返回它。像这样:

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;
}

答案 3 :(得分:2)

只需使用和ArrayList

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

              items.AddRange(yourVariable 
                        .Where(p => p.yourproperty == something)
                        .ToList());
            return items;
    }

答案 4 :(得分:1)

使用object,而不是var。但是,您必须使用反射来访问匿名类型范围之外的属性。

private object GetRowGroups(string columnName) 
...
var RowGroupList = new List<object>();
...

答案 5 :(得分:0)

在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());
}

但是您需要从Nuget软件包管理器中获取System.ValueTuple

无论如何,我建议给事物一个明确的名称,包括其用途,尤其是当它是公共API的一部分时。话虽如此,您应该考虑创建一个包含这些属性的类并返回该类型的列表。