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

C# 如何根据变量调用特定函数?,c#,C#,我正在生成一个1-1000之间的随机数。我有200个函数名为function1、function4、function10、function11等等。我想做的是根据生成的数字是否需要函数来执行特定的函数,如果不需要,则忽略它。 我的第一个想法是创建一个int[],其中包含触发函数的所有值,如果int[]包含随机数,则使用if语句来计算该数字。但我担心这对一个简单问题来说一定是一个非常粗糙的解决方案。 我知道做某事的“最佳方法”是主观的,但有没有更好的方法来实现这一点呢?更新:根据评论,我应该首先指

我正在生成一个1-1000之间的随机数。我有200个函数名为function1、function4、function10、function11等等。我想做的是根据生成的数字是否需要函数来执行特定的函数,如果不需要,则忽略它。 我的第一个想法是创建一个int[],其中包含触发函数的所有值,如果int[]包含随机数,则使用if语句来计算该数字。但我担心这对一个简单问题来说一定是一个非常粗糙的解决方案。
我知道做某事的“最佳方法”是主观的,但有没有更好的方法来实现这一点呢?

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

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


我不会解释您为什么要这样做,但我会尝试至少为您指出正确的方向,以便在您需要修改/扩展行为时,这不会成为一场彻底的噩梦:

您可以使用委托和字典将数字映射到函数调用。假设您的函数不带参数并返回void,您将执行以下操作:

var functionsMap = new Dictionary<int, Action>();
//map functions
var r = getSomeRandomNumber();

if (functions.TryGetValue(r), out var a)
    a(); //invoke function

如果函数采用参数或返回值,则应使用适当的委托:
操作、Func
等。

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

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

其中methodName可以使用您的随机数创建。

在不评论以您的方式命名200个函数是否明智的情况下,您可以使用反射来确定给定的
函数x()
是否存在,如下所示:

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);

请参阅以了解其背后的灵感。

反射可以用于此目的。我想在下面举个例子,不仅是为了问题的目的,也是为了将来的参考。当然,很多函数并不好,但下面的代码展示了一种方法,如果它们有相似的名称(比如以“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);
        }
    }
}
也可以使用下面的链接进行测试和观察


你真的有200种不同的功能吗?!您如何定义数字n是否必须调用函数f?可能是一个
字典
?要求很广泛,最佳解决方案取决于。你能说得更具体些吗?您可以使用反射按名称查找方法或路由调用(字典、索引器、开关/大小写等)。您试图解决的实际问题是什么?我特别不建议这样做,因为几乎可以肯定有更好的方法来实现OP试图实现的目标。拥有200个函数可能是一个非常糟糕的主意。@DavidG是的,我同意,但这仍然是一个展示一些良好实践的好机会。整个设置闻起来很难闻,这就是为什么我一开始就说我不会介入他为什么要这么做。但你这么做并不是真的在帮我。我不会投否决票,但我自己不会添加这个答案。@DavidG是的,你可能是对的,我会删除它。现在把它放在这里,我想它已经发布了。
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);
        }
    }
}