如何根据变量调用特定函数?

时间:2018-11-19 15:09:40

标签: c#

我正在生成一个1-1000的随机数。我有200个名为function1,function4,function 10,function 11等的函数。我要执行的操作是根据生成的数字是否需要一个函数来执行特定的函数,否则将其忽略。 我的第一个想法是创建一个包含将触发函数的所有值的int [],并且如果int []包含用于if语句以找出数字是什么的随机数。我担心这确实是一个简单问题的真正解决方案。 我知道做某事的“最佳方法”是主观的,但是有没有更好的方法来做到这一点?

4 个答案:

答案 0 :(得分:3)

更新:根据评论,我应该首先指出对200个函数执行此操作可能是一个好信号,表明您的设计中存在一些严重问题。这可能是XY question,您正在尝试以某种疯狂的方式解决问题,并询问预期的解决方案,而不是询问问题本身。

那是我将保留原始答案的原因,因为它在映射合理数量的函数调用时仍然是个好建议,这些函数调用可以/将在应用程序的生命周期中更改,或者在代码运行时动态更改。


我不会解释您为什么这样做,但是我将尽力至少为您指明正确的方向,这样当您需要修改/扩展行为时,这不会成为一个噩梦:

您可以使用委托和字典将数字映射到函数调用。假设您的函数不带任何参数并返回void,那么您将这样做:

id

映射功能只是添加键和值:

2

如果函数采用参数或返回值,则应使用适当的委托:var functionsMap = new Dictionary<int, Action>(); //map functions var r = getSomeRandomNumber(); if (functions.TryGetValue(r), out var a) a(); //invoke function 等。

答案 1 :(得分:0)

您可以使用反射来调用适当的方法:

Type exampleType = exampleObject.GetType();
MethodInfo exampleMethod = exampleType.GetMethod(methodName); 
exampleMethod.Invoke(this, null);

可以使用您的随机数创建methodName的地方。

答案 2 :(得分:0)

无需评论拥有200个以您的方式命名的功能的智慧,您可以使用反射来确定给定的functionX()是否存在,就像这样:

public void ExecuteDynamicMethod(int number)
{
    // Modify these two lines with your app's dll/exe and class type:
    Assembly assembly = Assembly.LoadFile("...Assembly1.dll");
    Type type = assembly.GetType("YourClassType");

    if (type != null)
    {
        MethodInfo methodInfo = type.GetMethod("function" + number);

        if (methodInfo != null)
        {
            object classInstance = Activator.CreateInstance(type, null);
            methodInfo.Invoke(classInstance, null);  // null = "no function arguments"
        }
    }
}

然后可以像给定值那样调用它

ExecuteDynamicMethod(14);

请参见this SO answer,以了解其背后的灵感。

答案 3 :(得分:0)

反射可用于此目的。我想给出并保持下面的例子,不仅是问题的目的,也是将来的参考。另外,当然,很多功能不好,但是下面的代码显示了名称相似的许多功能(例如,以“ function”关键字开头)可以使用的方法。

假设下面是Methods.cs

using System;
using System.Reflection;

namespace YourMethodNamespace
{    
    public class YourMethodClass
    {
        public void function1()
        {
            Console.WriteLine("Function-1");
        }

        public void function2()
        {
            Console.WriteLine("Function-2");
        }

        ...

        public void function200()
        {
            Console.WriteLine("Function-200");
        }

        public static void invokeMethodsDynamically(int randomNumber){
            Type yourClassType = typeof(YourMethodClass);
            ConstructorInfo yourClassConstructorInfo = yourClassType.GetConstructor(Type.EmptyTypes);
            object yourClassObject = yourClassConstructorInfo.Invoke(new object[]{}); 

            //If the constructor has parameters, then we can pass them by this way. Like below;
            /*ConstructorInfo yourClassConstructorInfo = yourClassType.GetConstructor(new[]{typeof(int)});
            object yourClassObject = yourClassConstructorInfo.Invoke(new object[]{3});
            */

            MethodInfo[] methodInfoArr = yourClassType.GetMethods();
            foreach(MethodInfo methodInfo in methodInfoArr){
                if(methodInfo.Name == "function" + randomNumber){
                    methodInfo.Invoke(yourClassObject, null);
                }
            }
        }
    }
}

下面说的是Program.cs

using System;
using YourMethodNamespace;

namespace YourProgramNamespace
{       
    public class YourProgramClass
    {
        public static void Main()
        {
            Random random = new Random();
            int randomNumber = random.Next(1, 201);             

            //If Methods.cs is in another Assembly

            /*string pathToDllAssembly = @"Domain.dll";
            Assembly dllAssembly = Assembly.LoadFrom(pathToDllAssembly);
            Type methodsClassType = dllAssembly.GetType("YourMethodNamespace.YourMethodClass");
            ConstructorInfo methodClassConstructorInfo = methodsClassType.GetConstructor(Type.EmptyTypes);
            object methodsClassObject = methodClassConstructorInfo.Invoke(new object[]{});
            MethodInfo methodInfo = methodsClassType.GetMethod("invokeMethodsDynamically");
            methodInfo.Invoke(methodsClassObject, new object[]{randomNumber});
            */

            YourMethodClass.invokeMethodsDynamically(randomNumber, null);
        }
    }
}

也可以通过下面的链接进行测试和观察。

https://repl.it/@erdsavasci/ReflectionTest