2012-02-23 104 views
0

我有以下的伪代码的工作原理:如何将参数传递给委托?

KeyBindings[Keys.Right] += Method1; 
KeyBindings[Keys.Right] += Method2; 

我遇到的是,我希望能够做到这一点的问题:

KeyBindings[Keys.Right] += Method1(argument); 
KeyBindings[Keys.Right] += Method2(argument1, argument 2); 

这可能吗?如果是这样,我如何重写我的代码来实现这一目标?


键绑定定义为:

Dictionary<Keys, Action> KeyBindings = new Dictionary<Keys, Action>(); 
+3

'KeyBindings'应该是什么?代表字典? – 2012-02-23 06:49:10

+0

@JeffMercado:请参阅编辑。 – Kittoes0124 2012-02-23 06:52:11

回答

3
class Program { 
    public static void Main() { 
     Dictionary<ConsoleKey, Action> KeyBindings = new Dictionary<ConsoleKey, Action>(); 
     KeyBindings[ConsoleKey.A] = null; 
     KeyBindings[ConsoleKey.A] +=() => Method1(12); 
    } 

    static void Method1(int arg) { 
    } 
} 
+0

对不起,在我发表评论之前,我还没有看到Kittoes的更新。你的代码实际上很好,因为我们实际上知道类型是什么,编译器可以推断出lambda是什么类型。 – 2012-02-23 07:07:23

+0

它的工作原理 - 见上面 – 2012-02-23 07:08:26

+0

@Dmitry Nogin:我早些时候对此发表评论,但它表示这篇文章不再存在,我非常难过。这工作完美无瑕,但我的问题是,我不明白为什么。你碰巧有一个固定的链接,我可以真正拿起在C#中的lambda表达式? – Kittoes0124 2012-02-23 07:10:02

0

它不工作的方式。此时您并未调用方法...您只是简单地告诉它应该使用哪种方法。

当您创建一个事件时,您可以指定包含这些参数的方法。参数在引发事件的地方传递。

下面是关于这个问题,这将有助于你更好地理解教程: http://www.csharp-station.com/Tutorials/lesson14.aspx

看一下下面的代码也可以帮助你把拼凑好一点。

public void SomeMethod() 
{ 
    //Assign the delegate 
    KeyBindings[Keys.Right] += Method1; 
} 

public PlaceWhereEventGetsRaised() 
{ 
    object argument1, argument2; 

    // set the arguments to something 

    if (KeyBindings[Keys.Right] != null) 
     KeyBindings[Keys.Right](argument1, argument2); 
} 

public void Method1(object argument1, object argument2) 
{ 
    // Do stuff 
} 

如果它看起来像你无法完成你想要做你的思维方式是什么,然后让我们知道你想要做什么,也许我们可以帮你找到正确的方法。

+0

我很害怕,因为我在这段时间一直没有运气。有什么办法可以重写这个来获得我想要的功能吗? – Kittoes0124 2012-02-23 06:55:01

+0

你能解释你正在寻找的功能应该做什么吗?更具体的你可以关于你的实际问题越好。 – 2012-02-23 07:00:24

+0

对,对不起。我试图将已知变量传递给已知函数。我有一个像Move()和Animate()这样的函数的静态类,我想将参数传递给它。在我目前的实现中,我不得不将这些参数传递到事件被触发的地方,而这没有任何意义。 – Kittoes0124 2012-02-23 07:12:29

3

那么在一般情况下,如果你想创建一个委托,将采取一些现有的功能和应用预设的一组参数,你就需要包装内的另一个功能。

例如,

考虑功能Foo()带一个string参数并返回一个int(具有相同签名Func<string, int>):

int Foo(string str) 
{ 
    return str.Length + 8941; 
} 

如果你想用它来创建一个委托,它返回字符串"bar"的调用Foo的结果,您可以这样做:

Func<int> foobar =() => Foo("bar"); 

所以请注意,我们创建了一个新的委托,lambda表达式不占用任何内容(在本例中)返回调用Foo("bar")的结果。


您可以将同样的事情在你的代码:

KeyBindings[Keys.Right] += new Action(() => Method1(argument)); 
KeyBindings[Keys.Right] += new Action(() => Method2(argument1, argument 2)); 
+0

** KeyBindings [Keys.Right] + =()=> Actions.MoveRight (arg1,arg2); **完美工作。我在评论第一个提出这个问题的人,但他似乎已经取消了他的答案。 – Kittoes0124 2012-02-23 07:07:19

+0

有趣.... – 2012-02-23 07:09:18

+0

@Kittoes:是的,这是不可能的,因为我们(最初)不知道我们在这里处理的是什么类型。但是既然你已经加入了它,它确实会像那样工作。根据你最初显示的内容,它暗示'Method1()'和'Method2()'是不同的类型,因此字典必须存储'Delegate'而不是像'Action'这样的特定类型。 – 2012-02-23 07:09:20

0

要做到,你必须创建一个具有内部固定的ARGS新方法,这样的事情。或者像这样的anonymus方法:

event += (s, someEventArgs) => Method1(s, someEventArgs, someOtherArgs)