将 Action<.., .., T > 作为没有预定义数量的动作参数的参数传递

Pass Action<.., .., T > as Parameter without a predefined number of action parameters

我有以下代码:

public doSomething(List<Int64> data, Int64 counter){
    //Do something
}    

public doSomethingNext(List<Int64> data, String Something){
    //Do something next
}    

public static void Loop<T>(Action<T> action) {
        //Do something before
        action(T);
    }
}

是否可以用这种通用的方式编写循环方法,以便我可以传递每个方法而不考虑方法的参数。像这样:

Loop(doSomething,....?);
Loop(doSomethingNext,...?);

@Edit 19:40 24-06-2015 更多信息

抱歉,'action(T);' 部分生成了 T 未知的错误。但是我把它填在那里,因为我不知道怎么做。

当我使用以下代码时,它适用于 Linq:

//Method
public static void Loop(Action action) {
    //Do something before
    action();
    }
}

//Call
Loop(() => doSomething(data, counter));

但是我很好奇它是否也可以在没有 Linq 的情况下工作? (用 < T > 之类的东西)

(附带问题,是否可以访问Loop函数中方法的参数?)

您可以将 Delegate... 作为参数,例如:

public static void Loop<T>(Delegate action) {
}

但是你必须

action.DynamicInvoke(someparameters);

所以使用反射来调用它......你会使用什么参数?


一般情况下如果调用者参数是"fixed"和"chosen",这个问题用partial application解决:

public static void Loop(Action action)
{
    action();
}

你可以像这样使用它:

Loop(() => Console.WriteLine("Hello"));

这里 Console.WriteLine() 有一个参数,但它是由调用者通过创建另一个方法(匿名方法)固定的,该方法具有 0 个参数,从中创建类型为 Action 的委托。

虽然您不需要从委托中删除所有参数:

public static void Loop<T>(Action<T> action)
{
    // generate some T value
    T value = GetValue<T>();

    // call action with a T parameter
    action(value);
}

然后:

Loop((int x) => Console.WriteLine("Some number: {0}", x));

在这种情况下,Console.WriteLine() 使用两个参数,其中一个是固定的 ("Some number: {0}"),另一个仍然是真正可变的 (x)。

调用 Loop 时使用 lambda 方法将您的方法转换为 Action:

 Loop(t => doSomething(t, counter));

 Loop(t => doSomethingNext(t, Something));