我可以在运行时在c#中动态构建函数吗?

时间:2014-06-25 16:33:56

标签: c# function dynamic runtime func

是否可以在运行时在c#中构建函数?

说我有这个方法:

List<object> DoSomeWork(List<object> listOfItems, bool boolA, bool boolB)
{
   var resultsList = new List<object>();

   foreach (var value in listOfItems)
   {
      var resultOfWork = CallFunction(value);

      if (boolA)
      {
          resultOfWork = AnotherFunctionCall(resultOfWork);
      }

      if (boolB)
      {
          resultOfWork = ThirdFunctionCall(resultOfWork);
      }

      resultsList.Add(resultOfWork);
   }

   return resultsList;
}

有没有办法可以在运行时动态构建一个函数,以防止需要为循环的每次迭代检查boolA和boolB?

在我脑海里,我有一些看起来像这样的东西:

List<object> DoSomeWork(List<object> listOfItems, bool boolA, bool boolB)
{
   Func<object, object> processor = (toProcess) =>
   {
       var resultOfWork = CallFunction(toProcess);
   }

   if (boolA)
   {
       processor += { resultOfWork = AnotherFunctionCall(resultOfWork); };
   }

   if (boolB)
   {
       processor += { resultOfWork = ThirdFunctionCall(resultOfWork); };
   }

   processor += { return resultOfWork; };

   var resultsList = new List<object>();

   foreach (var value in listOfItems)
   {
      resultsList.Add(processor(value));
   }

   return resultsList;
}

提前致谢。

2 个答案:

答案 0 :(得分:1)

有几种方法可以实现您希望实现的目标。您可以使用Linq.Expression在运行时构造函数。但是,由于您只有两个布尔标志,因此您可以采用更简单的方法,使用四个&#34;预先构建的&#34;函数对象,如下所示:

Func<object,object> processor;
if (boolA && boolB) {
    processor = v => ThirdFunctionCall(AnotherFunctionCall(CallFunction(x)));
} else if (boolA && !boolB) {
    processor = v => AnotherFunctionCall(CallFunction(x));
} else if (!boolA && boolB) {
    processor = v => ThirdFunctionCall(CallFunction(x));
} else {
    processor = v => CallFunction(v);
}
var resultsList = listOfItems.Select(processor).ToList();

大部分逻辑位于if条件链中,它列举了{boolA, boolB}对的所有四种可能性,并为processor仿函数分配了具有相应功能的lambda表达式

请注意,缺少明确的foreach循环,现在可以使用Select(...)后跟ToList()的LINQ调用替换它。

答案 1 :(得分:0)

(更新) 此示例构建并编译一个函数,该函数根据您传入的结果而变化。

    public static object CallFunction(object item) { return item; }
    public static object AnotherFunctionCall(object item) { return item; }
    public static object ThirdFunctionCall(object item) { return item; }

    public static MethodInfo CallFunctionMethodInfo = typeof(BuildFunction).GetMethod("CallFunction");
    public static MethodInfo AnotherFunctionCallMethodInfo = typeof(BuildFunction).GetMethod("AnotherFunctionCall");
    public static MethodInfo ThirdFunctionCallMethodInfo = typeof(BuildFunction).GetMethod("ThirdFunctionCall");

    public static Func<object, object> CreateFunc(bool boolA, bool boolB)
    {
        var objectParameter = Expression.Parameter(typeof(object));
        var returnVar = Expression.Variable(typeof(object), "returnVar");

        var commands = new List<Expression>();

        commands.Add(
            Expression.Assign(
            returnVar,
            Expression.Call(CallFunctionMethodInfo, objectParameter)));

        if (boolA)
        {
            commands.Add(
                Expression.Assign(
                returnVar,
                Expression.Call(AnotherFunctionCallMethodInfo, returnVar)));
        }

        if (boolB)
        {
            commands.Add(
                Expression.Assign(
                returnVar,
                Expression.Call(ThirdFunctionCallMethodInfo, returnVar)));
        }

        commands.Add(returnVar);

        var body = Expression.Block(new[] { returnVar }, commands);

        return Expression.Lambda<Func<object, object>>(body, objectParameter).Compile();
    }

从代码Func<object, object> processor = CreateFunc(boolA,boolB);

中调用此函数