发送静态方法+参数作为参数
问题描述:
我想这样做,但这是不可能的(不能从'void'转换为'System.Action')。发送静态方法+参数作为参数
class Program
{
public static void Main()
{
int n = 2;
ClassB cb = new ClassB();
cb.SetMethod(ClassA.MethodA(n)); //Cann't convert 'void' to 'System.Action<int>'
}
}
public class ClassA
{
public static void MethodA(int a)
{
//code
}
}
public class ClassB
{
Delegate del;
public void SetMethod(Action<int> action)
{
del = new Delegate(action);
}
public void ButtonClick()
{
del.Invoke();
}
}
public delegate void Delegate(int n);
我可以发送参数“N”,如在“使用setMethod”方法第二个参数,但我将不得不存储变量到后传递给“del.Invoke(PARAM)”。我想使用“del.Invoke()”。
答
您似乎对代表有误解。代表代表方法,而不是方法调用。如果您为方法提供参数,则它会成为方法调用。所以在这里:
cb.setMethod(ClassA.methodA(n));
ClassA.methodA(n)
是一个方法调用,你不能将它分配给委托。
基本上,在这个阶段你不能传递参数。您在调用委托时必须传递参数。例如
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();
答
cb.setMethod(new Action(ClassA.methodA));
答
是否要捕捉在调用点整数目前尚不清楚(例如,作为一个闭合),或者你是否有意传递一个参数明确的委托。
这里是前一种情况,当值被捕获:
public static void Main()
{
var n = 2;
var cb = new ClassB();
cb.setMethod(() => ClassA.methodA(n));
}
委托因而不知道捕获的变量,而只是定义为:
public delegate void Delegate();
然而,如果你不打算在int调用时传递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);
编辑 - 你认为还有更好的办法
没有真正的理由明确要求委托。 Action
和Func
(和Action<int>
,取决于以上)are already delegates。作为一种改进,您应该在调用之前检查该操作是否已分配。无效条件运算符将将其简化为_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.
}
}
使用setMethod有一个动作的参数了methodA返回无效参数,所以你必须要改变的返回类型methodA to Action –
@StuartLC即使此代码仍然不能工作,“ClassB.ButtonClick”方法正在调用单个参数动作的调用,但不提供参数。这有点不清楚他们想要在这里实现什么......也许他们只是想要一个没有参数的Action:'setMethod((=)=> classA.methodA(n)'你提到了吗? – Clint
请遵循C#的命名规则,这些细节使得你的代码不可读。信 –