代码之家  ›  专栏  ›  技术社区  ›  Jamin

使用for循环的实例号作为函数调用名的一部分

  •  2
  • Jamin  · 技术社区  · 7 年前

    这可能是一个愚蠢的问题,但我想了解如何更有效地做到这一点。

    我这里有一个代码示例:

    static void Main(string[] args)
    {
        string callName = "someFunction";
        for(int i = 0; i<2;i++)
        {
            callName = callName + Convert.ToString(i);
            //call callName function
        }
    
        Console.ReadLine();
    
    }
    
    public static void someFunction1()
    {
        Console.WriteLine("1");
    }
    public static void someFunction2()
    {
        Console.WriteLine("2");
    }
    

    我想根据for循环的索引为函数创建callname。

    编辑:

    我可能不完全理解如何正确使用EventListeners。为了更好地说明我在windows窗体中遇到的问题,我正在制作一个在面板[,]中包含一组面板的windows窗体。我想使用循环索引向每个面板添加动作侦听器。

    public test()
    {
        Panel[,] board = new Panel[2, 2];
        bool colorChange = true;
        //Create checkered panels
        for (int column = 0; column < 2; column++)
        {
            for (int row = 0; row < 2; row++)
            {
                if (colorChange)
                {
                    Panel currentPanel = CreatePanel(column * 100, row * 100 + 25, 100, 100, 255, 255, 255);
                    board[column, row] = currentPanel;
                    colorChange = false;
                }
                else
                {
                    Panel currentPanel = CreatePanel(column * 100, row * 100 + 25, 100, 100, 0, 0, 0);
                    board[column, row] = currentPanel;
                    colorChange = true;
                }
            }
            colorChange = !colorChange;
        }
        //unpack panels add controls to the form
        for (int column = 0; column < 2; column++)
        {
            for (int row = 0; row < 2; row++)
            {
                this.Controls.Add(board[column, row]);
            }
        }
        //Could for loop here... But what about event?
        board[0, 0].Click += new EventHandler(asd); //??
    }
    
    private void asd(object sender, System.EventArgs e)
    {
        MessageBox.Show("hi");
    }
    //Is there a better way to handle this part??
    private void asd2(object sender, System.EventArgs e)
    {
        MessageBox.Show("hi2");
    }
    
    public static Panel CreatePanel(int x, int y, int width, int height, int r, int g, int b)
    {
        Panel myPanel = new Panel();
        myPanel.Location = new Point(x, y);
        myPanel.Size = new Size(width, height);
        int[] rgb = { r, g, b };
        myPanel.BackColor = Color.FromArgb(rgb[0], rgb[1], rgb[2]);
        myPanel.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
        myPanel.Show();
        return myPanel;
    }
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   Tim Schmelter    7 年前

    导致反思方法的大多数问题是 XY-problems . 你要求X,但你实际上想要Y,并且认为你需要X。我相信这就是一个。

    为什么不简单地用参数实现一个方法?

    public static void PrintNumber(int number)
    {
        Console.WriteLine(number);
    }
    

    然后可以在循环中调用它:

    for(int i = 0; i < 2; i++)
    {
        PrintNumber(i);
    }
    

    如果您确实需要反射方法:

    Type t = typeof(Program);
    var methods = t.GetMethods(BindingFlags.Public | BindingFlags.Static)
        .Where(m => m.Name.StartsWith("someFunction"))
        .ToArray();
    
    for (int i = 1; i <= 2; i++)
    {
        MethodInfo method = methods.Single(m => m.Name == "someFunction" + i);
        method.Invoke(null, null);
    }
    
        2
  •  2
  •   Pac0    7 年前

    这不是反思,而是实现你想要的:

    class Program
    {
        public static void someFunction1()
        {
            Console.WriteLine("1");
        }
    
        public static void someFunction2()
        {
            Console.WriteLine("2");
        }
    
        static void Main(string[] args)
        {
            var functionList = new System.Collections.Generic.Dictionary<string, System.Delegate>() {
                { nameof(someFunction1), new Action(() => someFunction1()) },
                { nameof(someFunction2), new Action(() => someFunction2()) },
            };
    
            string callNameBase = "someFunction";
            for (int i = 1; i <= 2; i++)
            {
                string callName = callNameBase + i.ToString();
    
                functionList[callName].DynamicInvoke();
            }
    
            Console.ReadLine();
        }
    }
    

    (注意:我修复了您的示例中错误的索引:1、2与0、1,以及您构建函数名称的方式)


    然而,正如前面提到的,可能有更好的实践来实现您想要的。

    也许是某种战略模式。

    但由于我们不知道你想要实现什么,很难给你更好的建议。


    编辑 在您的详细问题之后:

    显然,您需要一个处理程序处理一半面板,另一个处理程序处理另一半面板。然后,您可以在创建过程中附加正确的事件处理程序:

        for (int row = 0; row < 2; row++)
        {
            if (colorChange)
            {
                Panel currentPanel = CreatePanel(column * 100, row * 100 + 25, 100, 100, 255, 255, 255);
                board[column, row] = currentPanel;
                colorChange = false;
                board[column, row].Click += new EventHandler(asd); // here
            }
            else
            {
                Panel currentPanel = CreatePanel(column * 100, row * 100 + 25, 100, 100, 0, 0, 0);
                board[column, row] = currentPanel;
                colorChange = true;
                board[column, row].Click += new EventHandler(asd2); // and here
            }
        }
    

    (希望我猜对了)