在IEnumerable中为方法编写匿名方法

时间:2009-05-25 20:42:19

标签: c# linq

我有以下代码(调用返回IEnumerable的方法):

    FibonacciWithLinq.Skip(delegate() {

                                          return 5;

    }
        );

skip的参数采用int(要跳过的项数)。我可以有一个单独的函数来确定这个数字(可能取决于某些因素)。但是,如果该方法将被Skip()方法使用,那么将它作为anon方法编写会很好。问题是,在上面的代码中,我收到了这个错误:

无法从用法推断出类型参数。尝试明确指定类型参数。

但我看不出上面的代码有什么问题。我能做什么?我很确定可以为上述场景编写一个匿名方法吗?

由于

5 个答案:

答案 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());
相关问题