发送静态方法+参数作为参数

时间:2017-06-15 05:23:02

标签: c#

我想做这样的事情,但这是不可能的。(无法从' void'转换为' System.Action&#39 ;)

IsAllowed()

我可以发送参数" n",作为" setMethod"中的第二个参数。方法,但我必须在传递给" del.Invoke(PARAM)"之后存储一个变量。我想使用" del.Invoke()"。

3 个答案:

答案 0 :(得分:2)

你似乎对代表有误解。代表代表方法,而不是方法调用。如果为方法提供参数,它将成为方法调用。所以这里:

cb.setMethod(ClassA.methodA(n));

ClassA.methodA(n)是一种方法调用,您无法将其分配给代理。

基本上,您无法在此阶段传递参数。您必须在调用委托时传递参数。 e.g。

del.Invoke(5);

但是你说你想总是写del.Invoke(),没有参数。那么,你不应该使用Action<int>,你应该使用Action,它不接受任何参数。

class Program
{
    public static void Main()
    {
        int n = 2;
        ClassB cb = new ClassB();

        cb.setMethod(() => ClassA.methodA(n));

    }
}

public class ClassA
{
    public static void methodA(int a)
    {
        //code
    }
}

public class ClassB
{
    Delegate del;
    public void setMethod(Action action)
    {
        del = new Delegate(action);
    }
    public void ButtonClick()
    {
        del.Invoke();
    }
}
public delegate void Delegate();

答案 1 :(得分:0)

cb.setMethod(new Action(ClassA.methodA));

答案 2 :(得分:0)

目前尚不清楚是否要在调用站点捕获整数(例如,作为闭包),或者是否要将参数明确传递给委托。

以下是前一种情况,其中捕获了值:

public static void Main()
{
    var n = 2;
    var cb = new ClassB();
    cb.setMethod(() => ClassA.methodA(n));
}

委托因此不知道捕获的变量,只是定义为:

public delegate void Delegate();

但是如果你打算在调用时传递int,那么int的值需要在ButtonClick中传递:

public static void Main()
{
    var cb = new ClassB();
    cb.setMethod(ClassA.methodA);
}
public class ClassB
{
    Delegate del;
    public void setMethod(Action<int> action)
    {
        del = new Delegate(action);
    }
    public void ButtonClick()
    {
        var n = 2;
        del.Invoke(n);
    }
}
public delegate void Delegate(int n);

编辑 - 重新认为有更好的方式

没有明确要求委托的真正理由。 ActionFunc(以及Action<int>,具体取决于上述内容)are already delegates。作为改进,您应该在调用之前检查操作是否已分配。 null条件运算符将简化为_action?.Invoke()。但是你可以更进一步,并通过在构造函数中要求它来防止动作被取消分配:

public class ClassB
{
    // Can be readonly if it is assigned only ever once, in the ctor.
    private readonly Action _action;

    public ClassB(Action action)
    {
        Contract.Assert(action != null);
        _action = action;
    }

    public void ButtonClick()
    {
        _action(); // i.e. no need for Invoke or null check.
    }
}