是否可以在运行时在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;
}
提前致谢。
答案 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);