在C#中使用不同参数回调各种方法的通用函数

时间:2014-06-27 09:46:54

标签: c# function generics generic-programming

我希望有一个能够调用任何函数并检索正确值的函数。

这些是我需要的一些例子:

var IList<Person> = InvokeFunction<IList<Person>>(repositoryPerson.GetAllPerson);

var Persion = InvokeFunction<Person>(repositoryPerson.GetPersonById, 10);

var int = InvokeFunction<int>(repositoryPerson.RunCustomStoreProcedure, 250,"text",521,10);

3 个答案:

答案 0 :(得分:1)

没有语法允许你这样做,因为没有语法允许你调用你的InvokeFunction方法并传入方法作为第一个参数调用。

具体来说,你可以声明InvokeFunction作为其第一个参数的唯一类型是某种委托类型,但你需要指定一个特定的委托类型,它会让你回到正方形1

现在,如果您稍微修改了语法,那么这是一个LINQPad程序演示:

void Main()
{
    var t = new Test();
    InvokeFunction<int>(t, "Add", 10, 20).Dump();
    InvokeFunction<int>(t, "Negate", 10).Dump();
    InvokeFunction<int>(t, "SemiRandom").Dump();
}

public class Test
{
    public int Add(int a, int b)
    {
        return a + b;
    }

    public int Negate(int value)
    {
        return -value;
    }

    public int SemiRandom()
    {
        return new Random().Next();
    }
}

public static T InvokeFunction<T>(object instance, string methodName, params object[] arguments)
{
    var method = instance.GetType().GetMethod(methodName, arguments.Select(a => a.GetType()).ToArray());
    return (T)method.Invoke(instance, arguments);
}

缺少此示例:

  1. 错误检查(空引用)
  2. 空参数处理(如果方法有重载,哪一个要选?)

答案 1 :(得分:0)

您可以使用反射和通用方法concpt来完成此操作。

理想情况下,您可以创建如下所示的通用方法

public T InvokeFunction<T>(repositoryPerson function, params object[] parameters)
    {
        object instance = Activator.CreateInstance(typeof(RepositoryPerson));
        MethodInfo mi = instance.GetType().GetMethod(function.ToString());

        return (T)mi.Invoke(instance, parameters);

    }

包含所有可能的函数名称的枚举会更好

        enum repositoryPerson
        {
            GetAllPerson, GetPersonById, RunCustomStoreProcedure
        }

在这里,您可以拥有一个表示存储库的所有功能的外观

public class RepositoryPerson
    {
        public IList<Person> GetAllPerson()
        {
            //return your result
            return null;
        }
        public Person GetPersonById(int id)
        {
            //return your result
            return null;
        }
        public int RunCustomStoreProcedure(int param1, string param2)
        {
            //return your result
            return 0;
        }
    }

现在你可以调用你的功能,如下所示

    IList<Person> persons = InvokeFunction<IList<Person>>(repositoryPerson.GetAllPerson);
    Person person = InvokeFunction<Person>(repositoryPerson.GetPersonById, 5);
    int val = InvokeFunction<int>(repositoryPerson.RunCustomStoreProcedure, 2, "3", "parame4");

请注意,这只是一个概念。当然,你必须在调用实际函数时进行类型检查,空引用等。

答案 2 :(得分:0)

它可以是通用函数:

    public static T InvokeFunction<T>(Func<T> functionName)
    {
        T obj = functionName.Invoke();
        return obj;
    }

使用方法:

   public static string method1(string a, string b)
    {
        return a + b;
    }

   public static int method2(int id1, string id2, string id3)
    {
        return 0;
    }


  var result1 = InvokeFunction<string>(() => method1("val1", "val2"));
  var result2 = InvokeFunction<int>(() => method2(123, "val1", "val2"));