我有以下代码(调用返回IEnumerable的方法):
FibonacciWithLinq.Skip(delegate() {
return 5;
}
);
skip的参数采用int(要跳过的项数)。我可以有一个单独的函数来确定这个数字(可能取决于某些因素)。但是,如果该方法将被Skip()方法使用,那么将它作为anon方法编写会很好。问题是,在上面的代码中,我收到了这个错误:
无法从用法推断出类型参数。尝试明确指定类型参数。
但我看不出上面的代码有什么问题。我能做什么?我很确定可以为上述场景编写一个匿名方法吗?
由于
答案 0 :(得分:3)
“值”和“没有返回值的参数的函数”之间没有自动转换(让我们称之为Func<T>
),也没有相反方向的自动转换。
要将Func<T>
转换为值T
,您必须在()
之后添加Func<T>
。要将值转换为() =>
,您可以将Func<T>
放在其前面。
如果您想调用某个接受Func<T>
的方法,则无法直接向其传递值,因此您必须将该值转换为() =>
,为此您可以将{ {1}}在它面前。
如果您想调用某个接受某个值的方法,则无法直接将其传递给Func<T>
,因此您必须将Func<T>
转换为值,方法是将()
转换为值
有些语言会在这些内容之间自动转换,但C#不会。
在你的情况下,你有一个接受一个值的函数,并且你试图传递一个函数,即使你已经有了一个值,所以除了给出值之外你不需要做任何特殊的事情这个功能。
int val = 5; // value
Func<int> f = () => val; // convert value to function
int val2 = f(); // convert back to value
“匿名方法”语法只是这种丑陋的老方法。你要做的事情有两个问题(除了这是不必要的事实)。
首先,您需要通过使用new Func<int>(...)
包装器显式声明委托类型来为编译器提供类型提示。
其次,您需要在其后添加()
以获取值。
FibonacciWithLinq.Skip(new Func<int>
(delegate()
{
return 5;
})());
但它不能被强调 - 这完全没有意义。
答案 1 :(得分:2)
如果你有什么东西可以确定要跳过多少,只需写下:
FibonacciWithLinq.Skip(HowManyToSkip())
或者您希望以不同的方式对其进行参数化,例如:
Func<int, IEnumerable<int>> skipper = x => FibonacciWithLine.Skip(x);
foreach (var i in skipper(5)) Console.WriteLine(i);
你问题中的代码是传递方法而不是常量int值,这是Skip想要的。也许你想跳过序列返回的值:如果是这样,Except()扩展方法就是你想要的:
FibonacciWithLinq.Except(x => (x == 5 || x == 7));
请注意,lambda语法只适用于:
FibonacciWithLinq.Except(delegate(int x) { return x==5||x==7; });
答案 2 :(得分:2)
如果你想跳过将函数作为参数,那么你需要编写一个扩展来执行此操作,然后你可以使用委托或lambda来提供一个可以被评估的函数来跳过你的元素想要省略。
public static class IEnumerableExtensions
{
public static IEnumerable<T> Skip( this IEnumerable<T> source, Func<int> toSkip )
{
return source.Skip( toSkip() );
}
}
FibonacciWithLinq.Skip( () => { return 5; } );
答案 3 :(得分:1)
除非我错了,否则正确的代码就是:
FibonacciWithLinq.Skip(5);
编辑:: 哦,你想要间接只是为了间接。我假设5个级别的间接是足够的,因为我们正在跳过5个元素?如果您需要更多信息,请与我们联系......
IEnumerable<int> FibannociSkip = new int[]{0, 1, 1, 2, 3, 5};
Func<Func<Func<Func<Func<int>>>>> f = ()=>(()=>(()=>(()=>(()=>5))));
foreach(var num in FibannociSkip.Skip(f()()()()()))
Console.WriteLine(num);
答案 4 :(得分:1)
Func<int> f = () => 5;
FibonacciWithLinq.Skip(f());