C# 如何使用Func在Linq中指定.NET匿名对象返回类型?

C# 如何使用Func在Linq中指定.NET匿名对象返回类型?,c#,linq,anonymous-types,C#,Linq,Anonymous Types,如何为匿名对象指定Func签名 new Func<DataSet, **IEnumerable<int>>** 在Func声明中将返回类型指定为IEnumerable时,我遇到了问题 我从表达式中得到的错误是 无法将表达式类型“System.Collections.Generic.IEnumerable”转换为返回类型“System.Collections.Generic.IEnumerable” 如何在func中指定IEnumerable 顺便说一句,我可以使用注释代

如何为匿名对象指定Func签名

new Func<DataSet, **IEnumerable<int>>**
在Func声明中将返回类型指定为IEnumerable时,我遇到了问题

我从表达式中得到的错误是

无法将表达式类型“System.Collections.Generic.IEnumerable”转换为返回类型“System.Collections.Generic.IEnumerable”

如何在func中指定IEnumerable

顺便说一句,我可以使用注释代码查询并完成它。 但在看到这个答案后,我想表现得更具表现力,尝试一些新的东西

编辑:最终结果

    public int GetCachedRootNodeId(IList<int> fromNodeIds, int forNodeId)
    {
        var result = forNodeId;

        const string spName = "spFetchAllParentNodeIDs";
        using (var ds = _df.ExecuteDatasetParamArray(_ConnectionString, spName, forNodeId))
        {
            if (DataAccessUtil.DataSetIsEmpty(ds)) return result;

            var orderParentNodeIDByLevelDesc = new Func<DataSet, IEnumerable<int>>(resultSet =>
                from DataRow row in DataAccessUtil.GetFirstTableRows(resultSet) 
                orderby DataAccessUtil.GetInt32(row, "Level") descending
                select DataAccessUtil.GetInt32(row, "ParentNodeID"));

            foreach (var parentNodeId in orderParentNodeIDByLevelDesc(ds))
            {
                if (fromNodeIds.Contains(parentNodeId))
                    return parentNodeId;
            }
        }

        return result;
    }

无法在声明中指定匿名类型。您必须为它创建一个命名类


Jon Skeet对此问题有自己的看法。

无法在声明中指定匿名类型。您必须为它创建一个命名类


Jon Skeet对此问题有自己的看法。

这里有一个想法-调用静态方法,让类型推断来完成:

public static Func<T, TResult> FuncOf(Func<T, TResult> func)
{
    return func;
}
基本上,您只需要Func部分告诉编译器它需要将lambda表达式转换为委托而不是表达式,以及委托的类型。它应该能够计算出给定FuncOf签名的类型

无论如何,值得一试


顺便说一句,我觉得你的评论版本更容易理解。为什么要引入额外的功能?或者你的计划是不把它作为局部变量,这样会更有意义,但是你不能使用var?或者可能是在循环外部而不是内部声明的局部变量?

这里有一个想法-调用静态方法,让类型推断来完成:

public static Func<T, TResult> FuncOf(Func<T, TResult> func)
{
    return func;
}
基本上,您只需要Func部分告诉编译器它需要将lambda表达式转换为委托而不是表达式,以及委托的类型。它应该能够计算出给定FuncOf签名的类型

无论如何,值得一试


顺便说一句,我觉得你的评论版本更容易理解。为什么要引入额外的功能?或者你的计划是不把它作为局部变量,这样会更有意义,但是你不能使用var?或者可能是在循环外部而不是内部声明了一个局部变量?

在这种情况下,您真正想要的是作为int。。。因此,只需将您的选择更改为:

select DataAccessUtil.GetInt32(row, "ParentNodeID"));
并将您的foreach更改为:

foreach (var nodeInfo in orderByLevelDesc(ds))
{
    if (fromNodeIds.Contains(nodeInfo))
        return nodeInfo;
}

在这种情况下,您真正想要的是。。。因此,只需将您的选择更改为:

select DataAccessUtil.GetInt32(row, "ParentNodeID"));
并将您的foreach更改为:

foreach (var nodeInfo in orderByLevelDesc(ds))
{
    if (fromNodeIds.Contains(nodeInfo))
        return nodeInfo;
}


我确实有一篇博客文章,但我认为这次我们不必绝望:事实上,我读到它时很喜欢。我只是想找个地方分享;我确实有一篇博客文章,但我认为这次我们不必绝望:事实上,我读到它时很喜欢。我只是想找个地方分享;这很有魅力。我只需要将FuncOf的签名更改为public static Func FuncOfFunc Func。调用它时,FuncOfresultSet到FuncOfDataSet resultSet,因为GetFirstTableRows方法需要一个数据集,但它没有被推断出来。为什么要把它弄得这么复杂?请看我上面的答案。@TheSoftwareEdi:我是想解决当前形势背后的问题,而不是仅仅解决这个我没有详细研究过的特殊案例,我必须承认。这两个有用的答案有不同的方式:当我必须返回多个属性时,你的答案很快就会派上用场。再次感谢你,这很有效。我只需要将FuncOf的签名更改为public static Func FuncOfFunc Func。调用它时,FuncOfresultSet到FuncOfDataSet resultSet,因为GetFirstTableRows方法需要一个数据集,但它没有被推断出来。为什么要把它弄得这么复杂?请看我上面的答案。@TheSoftwareEdi:我是想解决当前形势背后的问题,而不是仅仅解决这个我没有详细研究过的特殊案例,我必须承认。这两个有用的答案有不同的方式:当我必须返回多个属性时,你的答案很快就会派上用场。再次谢谢你,哈!,这是我的初衷。谢谢。如果有人真的需要一个多属性的anony类,Jon Skeet的答案很好。但在这种情况下,它只是一个int!我会选择Jon Skeet的回答作为答案,我返回了你提到的多个属性。哈!,这是我的初衷。谢谢。如果有人真的需要一个多属性的anony类,Jon Skeet的答案很好。但在这种情况下,它只是一个int!我会选择Jon Skeet的回答作为答案,我返回了您提到的多个属性。