从函数返回匿名类型

28

我能在函数中使用匿名类型作为返回类型,然后将返回的值添加到数组或某种集合中,并同时向新数组/集合添加一个额外的字段吗?请原谅我的伪代码...

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"));

}

可能是访问C#匿名类型对象的重复问题。 - nawfal
可能是返回匿名类型?的重复问题。 - Gert Arnold
返回元组,C# 7 特性。您可以在此处阅读更多信息:https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/ - Tanveer Badar
可能是如何从方法返回匿名类型?的重复。 - cdiggins
6个回答

21

不, 你不能从方法中返回匿名类型。如需更多信息,请阅读MSDN文档。请使用classstruct代替anonymous类型。

你应该阅读这篇博客文章- 可怕的肮脏黑客:返回匿名类型实例

如果你正在使用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
现在位于:https://codeblog.jonskeet.uk/2009/01/09/horrible-grotty-hack-returning-an-anonymous-type-instance/ - Marcelo Scofano Diniz

21

2
请始终引用外部链接的一小段内容。在这种情况下,第一个链接已经失效,因此您的回答相当无用。 - Teejay
1
“generating from usage”链接已损坏。 - dlchambers
1
@dlchambers:谢谢。我已经更改了链接,使用了来自wayback机器的存档。 - mellamokb
2
@mellamokb,除了OP之外,其他人也会在他们的谷歌搜索结果中看到这个结果,因此将每个未来用户重定向回谷歌完全没有帮助。感谢您的回答,但请在答案中内联重要信息,或者如果您只是重新指向其他资源,请留下评论。 - KyleMit

4
不可以直接返回匿名类型,但是可以使用即兴接口来返回它。示例代码如下:
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
很可爱,但我不确定这是否比仅仅将类型具体化更容易…(IDE中的工具可以帮助) - user166390

2

只需使用ArrayList即可。

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

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

1

使用object,而不是var。但你需要使用反射来访问匿名类型作用域之外的属性。

例如:

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

这可以通过 dynamic (C#4) 访问,但它会失去所有实际的类型安全性。 - user166390

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的一部分时。话虽如此,您应该考虑创建一个持有这些属性并返回该类型列表的类。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接