如何为匿名对象指定Func 签名?
new Func<DataSet, **IEnumerable<int>>**
我在 Func 声明中指定为 IEnumerable<> 的返回类型有问题
我从表达式中得到的错误是
Cannot convert expression type 'System.Collections.Generic.IEnumerable<{ParentNodeId:int}>' to returnt ype 'System.Collections.Generic.IEnumerable'
如何在 func 中指定 IEnumerable<{ParentNodeId:int}>?
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 orderByLevelDesc = new Func<DataSet, IEnumerable<int>>(resultSet =>
from DataRow row in DataAccessUtil.GetFirstTableRows(resultSet)
orderby DataAccessUtil.GetInt32(row, "Level") descending
select new { ParentNodeId = DataAccessUtil.GetInt32(row, "ParentNodeID") });
//// Get top-most parent's node ID first (higher the level, the more top-most the parent is)
//var query = from DataRow row in DataAccessUtil.GetFirstTableRows(ds)
// orderby DataAccessUtil.GetInt32(row, "Level") descending
// select new { ParentNodeId = DataAccessUtil.GetInt32(row, "ParentNodeID") };
//foreach (var nodeInfo in query)
foreach (var nodeInfo in orderByLevelDesc(ds))
{
if (fromNodeIds.Contains(nodeInfo.ParentNodeId))
return nodeInfo.ParentNodeId;
}
}
return result;
}
顺便说一句,我本可以使用注释代码“query”并完成它。 但是在看了这个答案之后想要更具表现力并尝试一些新的东西 Why doesn't C# have lexically nested functions?
编辑:最终结果
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;
}
最佳答案
这里有一个想法 - 调用一个静态方法并让类型推断来完成它:
public static Func<T, TResult> FuncOf(Func<T, TResult> func)
{
return func;
}
然后调用它:
var orderByLevelDesc = FuncOf(resultSet =>
from DataRow row in DataAccessUtil.GetFirstTableRows(resultSet)
orderby DataAccessUtil.GetInt32(row, "Level") descending
select new { ParentNodeId = DataAccessUtil.GetInt32(row, "ParentNodeID")
});
基本上你只需要“Func”部分来告诉编译器它需要将 lambda 表达式转换为委托(delegate)而不是表达式,以及委托(delegate)的类型。它应该能够计算出给定 FuncOf 签名的类型。
无论如何,值得一试。
顺便说一下,我发现您的注释掉的版本更容易理解。为什么要引入一个额外的功能?或者您是否计划不将其作为局部变量(这更有意义,但您不能使用var
)?或者可能是在循环外部而不是内部声明的局部变量?
关于c# - 如何使用 Func<T,Q> 在 Linq 中指定 .NET 匿名对象返回类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/596465/